我有点告诉某人,我们必须使用String.equals方法来比较两个字符串值,我们不能简单地在java中使用==运算符来比较字符串,并告诉他==将返回false,因为它不比较字符串值但是String对象引用值。
我已经写了这个例子来向他展示,但令我惊讶的是它始终为==运算符打印true。 这是代码
public void exampleFunc1(){
String string1 = "ABC";
String string2 = "ABC";
if(string1 == string2)
System.out.println("true");
else{
System.out.println("false");
}
System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
System.out.println(" Are they equal "+(string1.equals(string2)));
}
输出: -
他们是否正确
他们是否正确
这里的问题是在什么情况下==对象上的运算符可以打印为true,除了两个对象都是同一个实例?
答案 0 :(得分:2)
String
是少数特殊情况之一。
班级String
会保留一个特殊的“实习”String
池。方法myString.intern()
在此池中查找myString
。如果池中已存在具有相同内容的另一个String
,则返回指向它的指针。如果没有,则添加myString
(并返回指针)。
当您说myString= myString.intern() ;
时,您实际上正在使myString
引用共享副本或其可用于未来共享的基础String
(并且没有重复)。创建String
的大多数库方法都受此限制,尤其是String
文字。
使用包装类型Integer
,Long
等进行“实习”的其他情况。它们没有构造函数,但是返回预构建的共享对象的静态方法valueOf()
什么时候可以(通常256个值最接近零),而新的物体则不能。后者没有太大问题,因为这些类型比String
更轻量级。例如,Long
的有效载荷只有8个字节。 String
包含一个char[]
,即使是空的也是16个字节左右。
要回答您的问题,您无法依靠任何“实习”机制。它们在过去已经发生了变化,它们将来可能会发生变化(甚至从一个JVM变为另一个JVM),使您的代码无法使用。始终使用equals
。
答案 1 :(得分:1)
你应该使用
String string1 = new String("ABC");
String string2 = new String("ABC");
然后一切都会像你想的那样正确,
在这种情况下,“ABC”只是对const字符串的引用。
答案 2 :(得分:0)
编译器可能正在优化分配并且只创建一个String对象。如果使用显式String构造函数,==
操作应该按预期运行。