1
class A {
    String s = "abc";
}

class B {
    String s = "abc";

     static public void main(String[]args ) {
            A a = new A();
            B b = new B();
            System.out.println("a.s==b.s : " + (a.s==b.s));
     }
}

输出:

a.s==b.s : true

如果将文字写入类文件的“常量池”部分,那么 2 个类中的 2 个文字(相同的内容)如何使用相同的内部字符串?编译器如何将它们链接在一起?

4

3 回答 3

4

这与Java 语言规范第 3.10.5 节中的说明完全相同:

此外,字符串字面量总是引用 String 类的同一个实例。这是因为字符串字面量 - 或者更一般地说,作为常量表达式值的字符串(第 15.28 节) - 是“内部的”,以便使用 String.intern 方法共享唯一实例。

然后是一个例子,解释包括:

不同包中不同类中的文字字符串同样表示对同一 String 对象的引用。

String.intern()记录如下:

返回字符串对象的规范表示。

一个字符串池,最初是空的,由 String 类私下维护。

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

由此可见,对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为真时,s.intern() == t.intern() 才为真。

所有文字字符串和字符串值的常量表达式都是实习的。字符串文字在 Java™ 语言规范的第 3.10.5 节中定义。

所有这些都指向您在示例中看到的行为。

于 2012-05-20T13:08:07.273 回答
1

有一个字符串池,所有实习String对象都进入其中。它实际上是一个HashMap<String>. 请注意,该String.intern()方法返回一个String; 实施本质上是

if (stringPool.contains(this))
    return stringPool.get(this);
else {
    stringPool.put(this, this);
    return this;
}

在加载类时创建 String 对象时,它会被调用的结果替换,调用intern()的结果是在所有类之间共享类似的实例。

于 2012-05-20T13:03:51.513 回答
1

想象一个包含所有内部字符串的static final Set<String>in 。String.class所有共享同一个加载String类的类都将看到相同的实习字符串。由于String由根类加载器之一加载,因此它由单个 JVM 实例中的所有内容共享。

于 2012-05-20T13:10:16.317 回答