昨天去面试时遇到一个题 :String str= new String(“abc”);创建了几个对象?因为之前有了解过String pool,所以写了2个,可是主管说是1个。结果今天查了一下午String/ String pool的机制之后,发现各有各的说法,有没有高手能指导指导,给个明确的说法?
一
http://topic.csdn.net/u/20080929/02/4e0ef626-98ee-4d6d-96ed-fe40afe8290b.html?20773
深入研究java对String字符串对象的创建以及管理
原本在这篇文章中理解得比较好的
1. String a = "a" + "b" +"c";
编译时就可以确定的常量了,相当于String a ="abc",问题是String pool中会有“a”,“b”,“c”这3个对象吗?
String a = "a" + "b" + "c"; String pool中会有几个对象?
1. 不会有, String a = "a" + "b" + "c"; 只有1个对象
2. String a = new String("a");
String a1= a + "b";
这个是要运行时才确定的,问题是String pool中会有“b”吗?
是不是编译时遇到""里面的内容都会把他加入String pool中,
2. 会有b这个对象的。
3. 如果是这样String a = new String("a");
String a1= a + "b" + "c";
在String 池中是会生成"b", "c"还是"bc"?
3. .class文件中,ldc指令是从常量池中读取到栈顶 ,读取了三次,分别是"a", "b", "c"
4. String a="c";
String a1="b" + "c" + a; // 注意和4中的a + "b" + "c";的区别
4. 编译器会直接把"ab"处理为一个串处理,
在前面的字面常量串编译器可以直接优化连接,而在变量后面的编译器都通过弄成StringBuilder来append
可是后来在这一篇文章又看到:
http://topic.csdn.net/u/20080630/19/BEAB5990-FEE8-43F8-B6F4-882B4B04C89C.html
作者说:String a="ab"+"cd";创建了3个String对象????
又没看到有人提出异议,所以有点疑惑,
到底String a = "a" + "b" ;生成了多少个对象?
二
还有人说,JKD1.5之后,使用“+”时,String str="a"+"b"+"c",会生成第一个字符串(“a”)和最终的字符串(“abc”),因为JVM使用了StringBuilder来优化了,可是在Javap一下,
String str="a"+"b"+"c";
是直接从string pool中读取的,没有像他们说的先生成"a",再调用append()方法,逐个加入,最终生成“abc”。
搞了一个午,晕了,求解!!!
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16; //String bca直接读取String pool中的bca???
2: astore_1
3: getstatic #18; //Field java/lang/System.err:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
10: return
三
1. "当执行String a="abc";时,JAVA虚拟机会在栈中创建三个char型的值'a'、'b'和'c',然后在堆中创建一个String对象,它的值(value)是刚才在栈中创建的三个char型值组成的数组{'a','b','c'},最后这个新创建的String对象会被添加到字符串池中。"
这个还有一种说法:
2. 当执行String a="abc";时,会在字符串池中查找"abc",如果找到了,就返回池中对象的引用。找不到则在池中创建"abc",并返回其引用,而堆中没有创建对象。
我比较认可2,但是不知道1的说法哪里错?