Java:文字字符串

Don*_* Li 6 java string

class A { 

String s4 = "abc";

 static public void main(String[]args ) {

        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        A o = new A();
        String s5 = new String("def");

        System.out.println("s1==s2 : " + (s1==s2));
        System.out.println("s1==s1.intern : " + (s1==s1.intern()));
        System.out.println("s1==s3 : " + (s1==s3));
        System.out.println("s1.intern==s3.intern : " + (s1.intern()==s3.intern()));
        System.out.println("s1==s4 : " + (s1==o.s4));
 }
} 
Run Code Online (Sandbox Code Playgroud)

输出:

s1==s2 : true
s1==s1.intern : true
s1==s3 : false
s1.intern==s3.intern : true
s1==s4 : true
Run Code Online (Sandbox Code Playgroud)

我的问题:

1.会发生什么"String s1 = "abc"?我猜String对象是作为一个实习字符串添加到类String中的池?放在哪里?"永久生成"或只是堆(作为String Class实例的数据成员)?

2.会发生什么事"String s2 = "abc"?我想没有任何对象被创建.但这是否意味着Java Intepreter需要搜索所有被拦截的字符串?这会导致任何性能问题吗?

3.Seems String s3 = new String("abc") 不使用实习字符串.为什么?

4.会String s5 = new String("def")创建任何新的实习字符串吗?

use*_*421 5

  1. 编译器创建"ABC"的String对象常量池中,并生成字节码的赋值语句对它的引用.

  2. 见(1).没有搜索; 没有性能问题.

  3. 这会在运行时创建一个新的String对象,因为这就是'new'操作符的作用:创建新对象.

  4. 是的,对于"def",但由于(3)在运行时也创建了一个新的String.

3-4处的String对象未被实现.


Ste*_*n C 3

1.“String s1 =”abc”会发生什么?

在编译时,文字的表示形式将写入包含此代码的类的类文件的“常量池”部分。

加载类时,将读取类文件常量池中字符串文字的表示形式,并从中创建一个新的 String 对象。然后该字符串被保留,并且对保留字符串的引用被“嵌入”到代码中。

在运行时,对先前创建/保留的字符串的引用被分配给s1。(执行此语句时不会发生字符串创建或驻留。)

我猜想 String 对象作为实习字符串添加到 String 类的池中?

是的。但在执行代码时则不然。

它放置在哪里?“永久代”还是只是堆(作为 String 类实例的数据成员)?

它存储在堆的 permgen 区域中。(String 类没有静态字段。JVM 的字符串池是在本机代码中实现的。)

2.“String s2 =”abc”会发生什么?

加载时什么也没有发生。当编译器创建类文件时,它为该文字重用了与第一次使用该文字时使用的相同的常量池条目。因此,该语句使用的 String 引用与上一个语句使用的 String 引用相同。

我猜没有创建任何对象。

正确的。

但这是否意味着 Java 解释器需要搜索所有内部字符串?这会导致任何性能问题吗?

否,并且否。Java 解释器(或 JIT 编译代码)使用与为前一条语句创建/嵌入的相同引用。

3.似乎 String s3 = new String("abc") 没有使用 interned string。为什么?

实际情况比这更复杂。构造函数调用使用interned 字符串,然后创建一个新 String,并将 interned 字符串的字符复制到新 String 的表示形式。新创建的字符串被分配给s3

为什么?因为new指定为总是创建一个新对象(参见JLS),并且String构造函数被指定为复制字符。

4. String s5 = new String("def") 会创建任何新的实习字符串吗?

在加载时创建一个新的内部字符串(对于“def”),然后在运行时创建一个新的 String 对象,它是内部字符串的副本。(有关更多详细信息,请参阅前面的文字。)