Java:2个类中的2个文字(相同内容)如何使用相同的实习字符串?

时间:2012-05-20 13:02:05

标签: java string

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个文字(相同内容)如何使用相同的实习字符串?编译器如何将它们链接在一起?

3 个答案:

答案 0 :(得分:4)

这完全如Java Language Specification section 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()才为真。

     

所有文字字符串和字符串值常量表达式都是实体。字符串文字在The Java™Language Specification。的第3.10.5节中定义。

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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