【发布时间】:2012-12-18 12:10:11
【问题描述】:
正如这些 Stackoverflow 问题中所解释的:question 1 和 question 2 我知道“字符串文字”是 interned 时:
String s = "abc";
JVM 将创建一个新的字符串对象,而不是使用字符串池中的现有对象:
String s = new String("abc");
但是,在阅读了以下两个类似的陈述后,我有一个疑问。
当编译器遇到字符串字面量时,它会检查池以查看是否已经存在相同的字符串。如果找到匹配项,则对新字面量的引用将定向到现有字符串,并且不会创建新的字符串字面量对象。
在这种情况下,由于关键字“new”,我们实际上最终会得到稍微不同的行为。在这种情况下,对 String 字面量的引用仍被放入常量表(String Literal Pool)中,但是,当您遇到关键字“new”时,JVM 必须在运行时创建一个新的 String 对象,而不是使用常量表中的那个。
因此,如果我们在使用“new”并基于上述定义创建对象时,也将引用放在非池内存中AND 到池内存中。 当我们这样做时,JVM 不应该也返回相同的引用吗?:
String one = new String("test");
String two = "test";
System.out.println(one.equals(two)); // true
System.out.println(one == two); // false
因为在声明字符串字面量String three = "test"; 时它已经存在于池中?因此应该返回相同的引用并打印 true?或者前面的语句是否意味着它们将被放入池内存中,但在使用 new 运算符时被简单地跳过?
【问题讨论】:
-
如果有帮助,只需添加
System.out.println(one.intern() == two);将返回 true。