我对编译3行程序的答案和结果感到困惑.下面是代码及其操作码:http://pastebin.com/B1xxAjcp如果我不是完全错误的话,很明显
String s="abcd";
String s1=new String("efgh");
s.concat("ijkl");
Run Code Online (Sandbox Code Playgroud)
这些行对应于这些操作码:
1: istore_1
2: ldc #2 // String abcd
4: astore_2
5: new #3 // class java/lang/String
8: dup
9: ldc #4 // String efgh
11: invokespecial #5 // Method java/lang/String."<init>
":(Ljava/lang/String;)V
14: astore_3
15: aload_2
16: ldc #6 // String ijkl
18: invokevirtual #7 // Method java/lang/String.concat:
(Ljava/lang/String;)Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)
因此,根据我的理解ldc #index,不是创建新对象,而是创建对常量文字池的引用,并将其推送到堆栈.
创建一个新对象,new并在dup命令之前发生命令ldc #index.但在这个问题中有多少String对象..?,第二个答案说ldc #index暗示已经创建了String对象,解释如下:
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String ObjectOneObjectTwo
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
Run Code Online (Sandbox Code Playgroud)
As you see, there is only one String object, which contains "ObjectOneObjectTwo".
String s="abcd";
Run Code Online (Sandbox Code Playgroud)
文字"abcd"中的字符串在String池中创建.
String s1=new String("efgh");
Run Code Online (Sandbox Code Playgroud)
文字"efgh"中的字符串在String池中创建.创建了新的非实例String,将池中的String内容复制到其中
s.concat("ijkl");
Run Code Online (Sandbox Code Playgroud)
文字"ijkl"中的字符串是在字符串池中创建的.创建了新的非interned String,将两个interned Strings的内容复制到其中.
这String在池中创建了3个实例,在池中创建了2个非实例(不在池中)String.
编辑补充:该lcd字节码运算被推动的一个参考(值)String在池中压入堆栈.