2012-05-20 38 views
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)); 
    } 
} 

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

a.s==b.s : true 

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

+3

他们在课程加载时获得实习。 –

回答

1

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

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

当在加载类String对象创建,它是通过调用intern(),其中有像共享所有类中的实例结果的结果所取代。

+0

Thanks.So你的意思是当加载'B类'时,一个新的String对象被创建,但随后它可用于GC,因为它被加载'class A'时创建的实际字符串替代? –

+1

那么,我小心地说“有效”和“基本上”。当然没有必要这样做,而巧妙的实现可以避免它。 –

4

这也正是作为Java Language Specification section 3.10.5说:

而且,文字始终是一个字符串是指String类的同一个实例。这是因为字符串文字 - 或者更一般地说是常量表达式(§15.28)值的字符串 - 被“实施”,以便使用方法String.intern共享唯一实例。

有然后一个例子,对于其中的解释包括:在不同的包不同的类内

文字字符串同样表示为相同字符串对象的引用。

String.intern()是记录这样的:

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

最初为空的字符串池由类String私人维护。

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

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

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

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

1

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

相关问题