到目前为止,我一直在程序中使用==运算符来比较所有的字符串。 然而,我遇到了一个错误,将其中一个改为.equals(),它修复了这个错误。
==不好吗?什么时候应该使用,什么时候不应该使用?有什么不同?
到目前为止,我一直在程序中使用==运算符来比较所有的字符串。 然而,我遇到了一个错误,将其中一个改为.equals(),它修复了这个错误。
==不好吗?什么时候应该使用,什么时候不应该使用?有什么不同?
当前回答
在Java中,当使用==运算符比较两个对象时,它会检查两个对象是否指向内存中的相同位置。换句话说,它检查两个对象名称是否基本上引用了相同的内存位置。
Java String类实际上重写了Object类中的默认equals()实现——它重写了该方法,以便它只检查字符串的值,而不检查它们在内存中的位置。 这意味着如果调用equals()方法来比较两个String对象,那么只要实际的字符序列相等,两个对象就被认为是相等的。
==操作符检查两个字符串是否完全相同的对象。
equals()方法检查两个字符串是否具有相同的值。
其他回答
我同意zacherates的回答。
但是你能做的是在非文字字符串上调用intern()。
来自zacherates的例子:
// ... but they are not the same object
new String("test") == "test" ==> false
如果你实习非文字字符串相等为真:
new String("test").intern() == "test" ==> true
==操作符检查两个字符串是否完全相同的对象。
equals()方法将检查两个字符串是否具有相同的值。
Java有一个String池,Java在该池下管理String对象的内存分配。参见Java中的字符串池
当您使用==操作符检查(比较)两个对象时,它将地址相等性比较到字符串池中。如果两个String对象具有相同的地址引用,则返回true,否则返回false。但是如果你想比较两个String对象的内容,那么你必须重写equals方法。
equals实际上是Object类的方法,但它被重写到String类中,并给出了一个比较Object内容的新定义。
Example:
stringObjectOne.equals(stringObjectTwo);
但注意,它尊重String的情况。如果你想要不区分大小写的比较,那么你必须使用String类的equalsIgnoreCase方法。
让我们来看看:
String one = "HELLO";
String two = "HELLO";
String three = new String("HELLO");
String four = "hello";
one == two; // TRUE
one == three; // FALSE
one == four; // FALSE
one.equals(two); // TRUE
one.equals(three); // TRUE
one.equals(four); // FALSE
one.equalsIgnoreCase(four); // TRUE
是的,很糟糕……
==表示两个字符串引用是完全相同的对象。您可能听说过这种情况,因为Java保留了某种文字表(它确实如此),但情况并非总是如此。一些字符串以不同的方式加载,从其他字符串构造,等等,所以永远不要假设两个相同的字符串存储在相同的位置。
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检查留给您。