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)); } }
输出:
s1==s2 : true s1==s1.intern : true s1==s3 : false s1.intern==s3.intern : true s1==s4 : true
我的问题:
1.“String s1 =”abc“会发生什么?我想String对象是作为一个实习字符串添加到类String中的池中的?它放在哪里?”永久生成“或只是堆(作为数据) String Class实例的成员)?
2.“String s2 =”abc“会发生什么?我想没有任何对象被创建.但这是否意味着Java Intepreter需要搜索所有被拦截的字符串?这会导致任何性能问题吗?
3.Seems String s3 = new String(“abc”)不使用interned string.为什么?
4.Will String s5 = new String(“def”)创建任何新的实习字符串?
解决方法
1.What happens for “String s1 = “abc”?
在编译时,文字的表示形式被写入包含此代码的类的类文件的“常量池”部分.
加载类时,将读取类文件常量池中字符串文字的表示形式,并从中创建新的String对象.然后,该字符串被实现,然后对嵌入字符串的引用“嵌入”在代码中.
在运行时,对先前创建的/实例化String的引用被分配给s1. (执行此语句时不会创建字符串或实习.)
I guess the String object is added to the pool in class String as an interned string?
是.但不是代码执行时.
Where is it placed on? The “permanent generation” or just the heap(as the data member of the String Class instance)?
它存储在堆的permgen区域中. (String类没有静态字段.JVM的字符串池以本机代码实现.)
2.What happens for “String s2 = “abc”?
加载时没有任何事情发生.当编译器创建了类文件时,它会为第一次使用文字时使用的文字重用相同的常量池条目.因此,此语句使用的String引用与前一个语句使用的相同.
I guess no any object is created.
正确.
But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?
否和否.Java解释器(或JIT编译代码)使用与先前语句创建/嵌入相同的引用.
3.Seems String s3 = new String(“abc”) does not use interned string.Why?
它比这更复杂.构造函数调用使用interned字符串,然后创建一个新String,并将interned字符串的字符复制到新String的表示形式.新创建的字符串分配给s3.
为什么?因为new被指定为始终创建新对象(请参阅JLS),并且String构造函数被指定为复制字符.
4.Will String s5 = new String(“def”) create any new interned string?
在加载时创建一个新的实习字符串(对于“def”),然后在运行时创建一个新的String对象,该对象是实习字符串的副本. (有关详细信息,请参阅前面的文字.)