我对编译3行程序的答案和结果感到困惑。以下是代码及其操作码:http://pastebin.com/B1xxAjcp如果我不是完全错误,那很明显
String s="abcd";
String s1=new String("efgh");
s.concat("ijkl");
这些行对应于这些操作码:
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;
因此,根据我的理解ldc #index
意味着不是创建新对象,而是创建对常量文字池的引用,并将其推送到堆栈。
创建了一个新对象,new
和dup
命令发生在ldc #index
之前。但是在这个问题How many String object..?中,第二个答案说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
}
As you see, there is only one String object, which contains "ObjectOneObjectTwo".
答案 0 :(得分:5)
String s="abcd";
字符串“abcd”中的字符串在字符串池中创建。
String s1=new String("efgh");
字符串“efgh”中的字符串在String池中创建。 创建了新的非实习字符串,将池中的字符串内容复制到其中
s.concat("ijkl");
字符串“ijkl”中的字符串是在字符串池中创建的。 创建了新的非实习字符串,将两个实习字符串的内容复制到其中。
这在池中创建了3个String
个实例,在String
中创建了2个非实习(不在池中)的实例。
编辑添加: lcd
字节码操作将池中String
的引用(值)推送到堆栈。
答案 1 :(得分:2)
在第一行中,在字符串池中创建一个新字符串“abcd”。字符串对象“s”被赋予对该字符串的引用。在第二行中,在字符串池中创建另一个字符串“efgh”,并创建一个String“s1”类型的新对象,并且它将引用池中创建的新字符串。在第三行中,在字符串池中创建另一个字符串“ijkl”,在concat()操作之后,创建另一个新字符串“abcdijkl”,现在String对象“s”引用这个新创建的字符串。所以,字符串池中有3个对象,堆上有2个。
答案 2 :(得分:1)
我认为这里真实的是:
String s1=new String("efgh"); //this will create TWO objects : one in the pool and one in the heap.