29
class strb
{

    static public void main(String...string)
    {
         StringBuilder s1 = new StringBuilder("Test");
         StringBuilder s2 = new StringBuilder("Test");

         System.out.println(s1);
         System.out.println(s2);
         System.out.println(s1==s2);
         System.out.println(s1.equals(s2)); //Line 1
         System.out.println(s1.toString()==s2.toString()); //Line 2
         if(s1.toString()==s2.toString())System.out.println("True"); //Line 3
    }

}

输出是

Test
Test
false
false

对 .equals 有一个简短的问题。

无论对象内容如何,​​是否.equals仅当两个对象引用都指向同一个对象时才返回 true ?


编辑:现在我了解了有关的部分,.equals但为什么第 2 行和第 3 行也不返回true

编辑:我相信==查看参考变量的地址,因此 s1 和 s2 不能相等。如果我的假设不正确,请纠正我

4

8 回答 8

61

是的StringBuilder does not override Object's .equals() function,这意味着两个对象引用不相同,结果为假。

对于StringBuilder,您可以使用s1.toString().equals(s2.toString())

对于您的编辑,您==在两个不同的 String 对象上调用运算符。运算符将==返回 false,因为对象不同。要比较字符串,您需要使用String.equals()String.equalsIgnoreCase()

和你之前遇到的问题一样

于 2013-09-02T04:37:44.223 回答
4

该类StringBuilder不提供重写equals()方法。因此,当在 的实例上调用该方法时,将执行该方法StringBuilder的类实现,因为.ObjectStringBuilder extends Object

源代码是

public boolean equals(Object obj) {
    return (this == obj);
}

它只是比较引用相等性。

于 2013-09-02T04:39:36.630 回答
3

如您所提到.equals的,该类的默认实现。Object

其他类可以覆盖此行为。 StringBuilder不是其中之一。

String 是其中之一,它覆盖它以确保两个对象的 String 表示产生相同的字符序列。 字符串 API

请参阅相关特定对象的文档。

于 2013-09-02T04:37:38.953 回答
2

对于您的第一个答案,请查看@abmitchell 的答案

对于您的编辑:

在 Java 中,String 是一个对象,我们不能通过使用来比较对象的值相等性==

==用于比较原始值或对象引用。

为了比较我们equals()在 Java 中使用的 Object 值

于 2013-09-02T04:49:34.787 回答
2

检查equals方法的合同:

它必须是一致的(如果对象没有被修改,那么它必须保持返回相同的值)。

这就是为什么 StringBuilder 无论其内容如何都不会覆盖它的原因。

让我们以上面的例子为例。

     StringBuilder s1 = new StringBuilder("Test");
     StringBuilder s2 = new StringBuilder("Test");

也许,对您来说,由于当前的运行时间值,预计会s1.equals(s2)返回。true

但是,如果您更改添加行怎么办:

    s1.append("abc");

那么 s1 和 s2 将有不同的字符串内容,并且s1.equals(s2)应该是false. 但这与一致性相矛盾。

于 2014-06-06T13:13:07.950 回答
1

StringBuilder并且StringBuffer不覆盖Objectclass.but 的 equals 函数,而是覆盖该equals方法。的功能Object是这个

public boolean equals(Object obj) {
    return (this == obj);
    }

你可以这样写你的代码。

System.out.println(s1.toString() == s2.toString());
System.out.println(s1.toString().equals(s2.toString()));
于 2013-09-02T04:51:13.293 回答
1

StringBuilder类没有equals()像类中那样的方法的实现String

所以它执行默认的 Object 类功能,它再次只检查地址等价性,在这种情况下是不一样的。所以它打印错误。

注意 1:您也可以==在对象上使用运算符,但它只是检查两个对象的地址是否相同。

注2==运算符在比较字符串常量池中创建的两个String对象时起到了很好的作用,以确定它是否真的在字符串常量池中创建了一个新对象。

于 2013-12-10T12:12:07.443 回答
0

同意上述两个回复,但我值得注意的是实际比较你可以做的内容:

System.out.println(s1.toString().equals(s2.toString())); //Line 1
于 2013-09-02T04:39:15.633 回答