到目前为止,我一直在程序中使用==运算符来比较所有的字符串。 然而,我遇到了一个错误,将其中一个改为.equals(),它修复了这个错误。

==不好吗?什么时候应该使用,什么时候不应该使用?有什么不同?


当前回答

==测试引用是否相等(它们是否是同一个对象)。

.equals()测试值是否相等(它们是否包含相同的数据)。

Objects.equals()在调用.equals()之前检查是否为空,因此不必这样做(在JDK7中可用,在Guava中也可用)。

因此,如果你想测试两个字符串是否具有相同的值,你可能会使用Objects.equals()。

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

你几乎总是想使用Objects.equals()。在极少数情况下,您知道您正在处理的是实习字符串,您可以使用==。

来自JLS 3.10.5。字符串:

而且,string字面值总是引用string类的同一个实例。这是因为字符串字面量——或者更一般地说,是常量表达式的值的字符串(§15.28)——被“internned”,以便使用string .intern方法共享唯一的实例。

在JLS 3.10.5-1中也可以找到类似的例子。

其他需要考虑的方法

String.equalsIgnoreCase()忽略大小写的值相等性。但是要注意,在各种与区域设置相关的情况下,此方法可能会产生意想不到的结果,请参阅这个问题。

String. contentequals()将String的内容与任何CharSequence的内容进行比较(自Java 1.5起可用)。在进行相等比较之前,不必将StringBuffer等转换为String,但将null检查留给您。

其他回答

您还可以使用compareTo()方法来比较两个string。如果compareTo结果为0,则两个字符串相等,否则被比较的字符串不相等。

==比较引用,不比较实际字符串。如果你确实使用new string (somestring).intern()创建了每个字符串,那么你可以使用==操作符来比较两个字符串,否则只能使用equals()或compareTo方法。

==比较对象的引用值,而java.lang.String类中的equals()方法比较String对象的内容(与另一个对象)。

==比较对象引用。

.equals()比较字符串值。

有时==会产生比较String值的错觉,如下所示:

String a="Test";
String b="Test";
if(a==b) ===> true

这是因为当您创建任何String字面值时,JVM首先在String池中搜索该字面值,如果找到匹配,则将相同的引用给予新的String。因此,我们得到:

(a==b) ==>为真

                       String Pool
     b -----------------> "test" <-----------------a

但是,==在以下情况下失效:

String a="test";
String b=new String("test");
if (a==b) ===> false

在这种情况下,对于new String("test"),语句new String将在堆上创建,并且该引用将被赋予给b,因此b将被赋予堆上的引用,而不是在String池中。

现在a指向String池中的String,而b指向堆中的String。因此我们得到:

如果(a==b) ==>假。

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

而.equals()总是比较String的值,所以在这两种情况下都是true:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

所以使用.equals()总是更好。

是的,==不利于比较字符串(实际上是任何对象,除非您知道它们是规范的)。==只是比较对象引用。.equals()测试是否相等。对于字符串,它们通常是相同的,但正如你所发现的,这并不总是保证的。

是的,很糟糕……

==表示两个字符串引用是完全相同的对象。您可能听说过这种情况,因为Java保留了某种文字表(它确实如此),但情况并非总是如此。一些字符串以不同的方式加载,从其他字符串构造,等等,所以永远不要假设两个相同的字符串存储在相同的位置。

Equals为你做真正的比较。