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