Java:为什么两个类中的两个文本(相同的内容)使用相同的内部字符串?

Java:为什么两个类中的两个文本(相同的内容)使用相同的内部字符串?,java,string,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)); } } 如果文本被写入类

输出:

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));
     }
}
如果文本被写入类文件的常量池部分,为什么2个文本2个类中的相同内容使用相同的插入字符串?编译器是如何将它们链接在一起的?

有一个字符串池,所有插入的字符串对象都会进入其中。它实际上是一个HashMap。注意String.intern方法返回一个字符串;其实施基本上是

a.s==b.s : true
加载类时创建字符串对象时,它将被调用intern的结果替换,该结果将在所有类之间共享类似实例。

有一个字符串池,所有intern字符串对象都将进入其中。它实际上是一个HashMap。注意String.intern方法返回一个字符串;其实施基本上是

a.s==b.s : true

加载类时创建字符串对象时,它将被调用intern的结果所替换,该结果将在所有类之间共享类似的实例。

这与以下内容完全相同:

此外,字符串文字总是引用类字符串的同一实例。这是因为字符串文字-或者更一般地说,是常量表达式§15.28的值的字符串-被插入,以便使用string.intern方法共享唯一实例

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

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

记录如下:

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

最初为空的字符串池由类字符串私下维护

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

因此,对于任意两个字符串s和t,s.intern==t.intern为真当且仅当s.equalst为真时

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


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

这正是在:

此外,字符串文字总是引用类字符串的同一实例。这是因为字符串文字-或者更一般地说,是常量表达式§15.28的值的字符串-被插入,以便使用string.intern方法共享唯一实例

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

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

记录如下:

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

最初为空的字符串池由类字符串私下维护

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

因此,对于任意两个字符串s和t,s.intern==t.intern为真当且仅当s.equalst为真时

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


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

想象String.class中包含所有内部字符串的静态最终集。共享相同加载字符串类的所有类都将看到相同的插入字符串。由于String是由一个根类加载器加载的,所以它由单个JVM实例中的所有对象共享。

想象一下String.class中包含所有内部字符串的静态最终集。共享相同加载字符串类的所有类都将看到相同的插入字符串。因为字符串是由一个根类加载器加载的,所以它由单个JVM实例中的所有对象共享。

它们在类加载时被拘留。它们在类加载时被拘留。谢谢。那么,你是说加载“B类”时,创建了一个新的String对象,但它立即可用于GC,因为它被在加载“class a”时创建的插入字符串替换了?好吧,我很小心地说,实际上是有效的。当然不需要这样做,聪明的实现可以避免这种情况。谢谢。那么你的意思是当加载“class B”时,会创建一个新的String对象,但它会立即用于GC,因为它被加载“class a”时创建的插入字符串所取代?好吧,我谨慎地说,这是有效和必要的 很好。当然不需要这样做,聪明的实现可以避免这种情况。