3

使用 intern 方法时字符串常量池中没有对应对象的字符串返回堆中存在的同一对象的引用。不应该返回由 String 常量池中的 intern 方法新创建的完全不同对象的引用吗? 考虑给定的一段代码。

class  Test{
public static void main(String[] args) {
    String s1 = new String("durga");
    String s2 = s1.concat("software");
    String s3 = s2.intern();
    System.out.println(s2 == s3);
    String s4 = "durgasoftware";
    System.out.println(s3 == s4);
 }
}

输入: deep (master *) LanguagePackageInJava $ javac Lecture14.java
deep (master *) LanguagePackageInJava $ java 测试
输出: true
true

第一个打印语句的输出如何为真?据我说s2是堆区的对象,而s3应该是字符串常量池区的对象。它们怎么能指向同一个对象?

4

2 回答 2

1

正如您在 java文档中看到的:

返回字符串对象的规范表示。[...] 当调用 intern 方法时,如果池中已经包含一个等于该 String 对象的字符串,该字符串由 equals(Object) 方法确定,则返回池中的字符串。否则,将此 String 对象添加到池中并返回对该 String 对象的引用。

所以实际上它首先实习了被引用的字符串s2,然后返回该引用(将其存储在 中s3)。这导致 s2 和 s3 指向同一个对象。

如果字符串池已经包含字符串(通过将语句移动到方法的顶部来尝试),则返回 this而不是internString s4 = "durgasoftware"引用的字符串。这产生了另一个结果。s2

于 2018-09-05T07:43:17.333 回答
0

原因是 s2 的值被用作"intern"。该对象只是被推入池中以供重用。下面我期望不同的结果,首先实习相同的字符串s0

String s0 = "durga".concat("software").intern();
String s1 = "durga";
String s2 = s1.concat("software");
String s3 = s2.intern();
System.out.println(s2 == s3); // false
System.out.println(s3 == s0); // true

通过历史的实施发生了intern变化。一开始,字符串池位于“永久内存”中,可能会使内存混乱。因此,由 XML 解析器嵌入的 XML 标记使用它们自己的映射。

我希望代码确实产生假+真。

于 2018-09-05T07:58:21.990 回答