似乎 JDK7 以与以前不同的方式处理实习生。
我使用 build 1.7.0-b147 对其进行了测试并得到“两者相等”,但是当使用 1,6.0_24 执行它(相同的字节码)时,我没有收到消息。
它还取决于该String b2 =...
行在源代码中的位置。以下代码也不会输出消息:
class Test {
public static void main(String... args) {
String s1 = "Good";
s1 = s1 + "morning";
String s2 = "Goodmorning";
System.out.println(s1.intern()); //just changed here s1.intern() and the if condition runs true
if(s1 == s2) {
System.out.println("both are equal");
} //now it works.
}
}
似乎intern
在其字符串池中找不到字符串后,将实际实例 s1 插入池中。创建 s2 时 JVM 正在使用该池,因此它得到与 s1 相同的引用。另一方面,如果首先创建 s2,则该引用将存储到池中。
这可能是从 Java 堆的永久生成中移出实习字符串的结果。
在这里找到:JDK 7 中解决的重要 RFE
在 JDK 7 中,interned 字符串不再分配在 Java 堆的永久代中,而是与应用程序创建的其他对象一起分配在 Java 堆的主要部分(称为年轻代和年老代)中. 此更改将导致更多数据驻留在主 Java 堆中,而永久代中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序只会看到相对较小的堆使用差异,但加载许多类或大量使用 String.intern() 方法的大型应用程序将看到更显着的差异。
不确定这是否是一个错误以及来自哪个版本...... JLS 3.10.5 状态
显式实习计算字符串的结果是与任何具有相同内容的预先存在的文字字符串相同的字符串。
所以问题是如何解释预先存在的,编译时或执行时:“早安”是否预先存在?
我更喜欢它在 7 之前实施的方式......