public class A {
static String s1 = "I am A";
public static void main(String[] args) {
String s2 = "I am A";
System.out.println(s1 == s2);
}
}
以上程序输出“true”。两者是两个不同的标识符/对象输出是如何“真”?
我的理解是JVM会为每个对象创建不同的引用,如果是这样,输出是如何生效的?
答案 0 :(得分:20)
Java管理String
文字池。它尽可能地重用这些文字。因此,这两个对象实际上是相同的String
对象,==
返回true。
我相信这叫做string interning
答案 1 :(得分:6)
==检查变量是否指向对象的完全相同的实例。您创建的两个字符串文字指向内存中的相同位置,因此它们是相等的。字符串文字被实现,因此相同的字符串文字是内存中的同一个对象。
如果你要做
String s = new String("foo");
String t = new String("foo");
然后==将返回false并且s.equals(t)将返回true。
答案 2 :(得分:5)
因为Java Language Specification说:
字符串文字 - 或者更一般地说, 作为值的字符串 常数表达式(§15.28) - 是 “实习”以便分享独特 实例,使用该方法 的String.intern。
答案 3 :(得分:5)
这是因为编译器执行了内存优化...即,String
常量(即 - String
由同一个String
文字构成)使用相同的{{1对象,因为String
是不可变的。 Strings
运算符只检查两个对象是否是同一个实际对象。
如果你能抓住Joshua Bloch和Neal Gafter的Java Puzzlers这本书,看一下拼图13,“动物农场”......他对这个问题有很好的建议。我将复制一些相关文字:
“您可能知道==
类型的编译时常量被实现[JLS 15.28]。换句话说,任何两个类型为String
的常量表达式都表示相同的字符序列由相同的对象引用...你的代码应该很少,如果有的话,依赖于字符串常量的实习.Interning的设计只是为了减少虚拟机的内存占用,而不是作为程序员的工具...当比较对象引用时,您应该优先使用String
方法而不是equals
运算符,除非您需要比较对象标识而不是值。“
这是我在上面提到的参考资料......在我的书中第30-31页。
答案 4 :(得分:1)
您没有比较字符串的内容。您只是比较对象的引用。您应该使用equal方法(它是String类的成员)。或者您可以使用compareTo方法(也在相同的String类下)来检查返回值是否为零。
请注意上面的文字更多地是对问题的原始状态的强烈建议,因为看起来OP似乎并不知道幕后的实际过程。
其他人建议进行内部连接是正确的。要回答这个问题,我没有足够的时间去阅读Java Puzzlers的书。我确实怀疑在编译时设置相同的引用,但我不知道如何找到对它的引用。