代码之家  ›  专栏  ›  技术社区  ›  Andrei Ciobanu

Java中的字符串:equals vs==[重复]

  •  5
  • Andrei Ciobanu  · 技术社区  · 14 年前

    可能重复:
    How do I compare strings in Java?

      String s1 = "andrei";
      String s2 = "andrei";
    
      String s3 = s2.toString();
    
      System.out.println((s1==s2) + " " + (s2==s3));
    

    s2.toString()实际返回的是什么?实际位置 (s2.toString()) ?

    15 回复  |  直到 8 年前
        1
  •  7
  •   Robert Munteanu    14 年前

    首先 String.toString

    /**
     * This object (which is already a string!) is itself returned.
     *
     * @return  the string itself.
     */
    public String toString() {
        return this;
    }
    

    其次,字符串常量是内部的,因此s1和s2在幕后被更改为同一个字符串实例。

        2
  •  7
  •   mdma    14 年前

    String.intern() 可用于确保相等的字符串具有相等的引用。字符串常量是 intern 埃德,所以 s1 s2 String.toString() 简单地返回本身,也就是说, a.toString() 当a是字符串时,返回a。所以,s2也==s3。

    一般来说,字符串不应通过引用相等进行比较,而应通过值相等进行比较,使用 equals() . 原因是很容易得到两个等价但不同引用的字符串。例如,在创建子字符串时。这条规则的一个例外是,如果您知道两个字符串都 实习生 你可以事先给他们打电话(或者作为比较的一部分给他们实习)

        3
  •  7
  •   pcalcao    12 年前

    new String("something") 您正在强制Java创建一个全新的对象。

    ="something" ,该字符串存储在常量池中,由JVM进行优化。因此,当您将另一个引用指定给同一个常量时,常量池中存储的对象将被重用,基本上,它是同一个对象。

        4
  •  3
  •   JonH    14 年前

    在比较java字符串时,应该使用.equals和not==。

    ==比较引用,因此s2.ToString()返回s2。

    In Sun’s JVM, the interned Strings (which includes String literals) are
    

    称为perm gen,其中JVM 还加载类和存储 本机编译的代码。然而 普通对象堆。

        5
  •  3
  •   Andreas Dolk    14 年前

    根据java虚拟机规范:

    "andrei" 是字符串文本,因此是“interned”。因此两个字符串 s1 s2 引用同一个字符串对象,一个包含内容的内部字符串 “安德烈” .

    因此 (s1 == s2) && (s1.equals(s2)) true String#toString() 不会创建新的 String (就像许多其他的 字符串 this . 因此 s2 == s3 是的 .

        6
  •  2
  •   Peter Lawrey    12 年前

    ==比较引用并创建两个不同的对象。

    我知道对于非基本类型,当我们做“==”,

    字符串不是基元。参考资料将 == 指的是同一个物体。

        7
  •  1
  •   Thomas Lötzer    14 年前

    == 比较参考资料,你可以从 s2 == s3 是真的吗 s2.toString() 返回s2。

        8
  •  1
  •   Riduidel    14 年前

    由于String是不可变的,toString方法的一个有用实现是在String类中返回这个值。

    例如,my rt.jar包含以下实现:

    public String toString() {
    return this;
    }
    

    因此,与 s3 与关联的相同 s2 .

    考虑到 s1==s2 语句,这是由于自动调用 intern() 对于所有常量字符串。这意味着在编译时,s2初始化代码将被替换为 s2=s1

        9
  •  1
  •   michael nesterenko    12 年前

    String.intern() )比较字符串是安全的 == 对于所有其他情况,您应该使用 equals .

    在你的情况下,你定义你自己的类型 MyString 它和java有一些共同点 String s s1 比较两个不同对象的引用,这就是 false

        10
  •  1
  •   Radu Stoenescu    12 年前

    每一个例子 MyString 位于不同的内存位置,因此,忘记了实例的内容,对于每两个不同的实例 == false .

    以防 String 同学们,当你们做作业的时候,有一个很小但很重要的区别 字符串 String s = "foo"; ),一个新的内存位置将被“foo”占用,前提是“foo”以前没有作为文本遇到。如果是这样(即。 String s = "foo"; String otherS = "foo"; ), otherS 只是要引用已经存在的“foo”。

    这种行为称为 String pooling .

        11
  •  1
  •   jlordo    12 年前

    比较时 s == s1 MyString

    enter image description here

    s s1 是不同的对象,但它们的属性指向 toto .

    它们是不同的对象,因为您创建它们的方式不同:

    MyString s = new MyString("toto");
    MyString s1 = new MyString("toto");
    

    s==s1 会回来的 false true

    MyString s = new MyString("toto");
    MyString s1 = s;
    

    这就是结果

    enter image description here

        12
  •  1
  •   Theolodis    11 年前

    new . 现在, 这个 == 运算符不比较两个内存地址

    javac ,确实优化了代码。通过类似的优化 字串常数 被放置在一个 同一个存储单元 . 如果你做了以下的事情,那么你的结果也会是一样的 String 物体。

    String s2 = new String("toto");
    String s3 = new String("toto");
    System.out.println(s2==s3); //yields false!!
    

    你要走的路是。等于(其他)。 为此,必须在Mystring类中实现equals方法:

    class MyString{
    
        private String s;
    
        public MyString (String s){
            this.s = s;
        }
    
        public String getContent(){
            return s;
        }
    
        @Override
        public boolean equals(Object other){
            if(other instanceof MyString){
                MyString compareTo = (MyString) other;
                return this.s.equals(compareTo.getContent());
            }
            return false;
        }
    }
    
        13
  •  0
  •   lzlstyle    13 年前

        14
  •  0
  •   NPE    12 年前

    当你使用 == 只保证回来 true

    String s1 = "...";
    String s2 = s1;    // reference assignment!
    

    在这里, s1 == s2 可能会回来,也可能不会回来

    要比较两个字符串的内容,请使用 equals()

    if (s1.equals(s2)) {
       ...
    }
    
        15
  •  -1
  •   nob    14 年前

    s2.toString()正在返回字符串表示形式。因为它已经是一个字符串了,所以它返回它自己(这就是为什么比较是正确的)。

    所有字符串都分配在堆上,coparison操作符只是比较它们是否是同一个对象(这就是为什么s1!=s2)。