从此测试代码:
public class Test {
public static void main(final String[] args) {
String temp = "a" + "b" + "c";
}
}
你得到这个字节码:
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String abc
2: astore_1
3: return
使用这个常量池:
Constant pool:
#1 = Methodref #4.#13 // java/lang/Object."<init>":()V
#2 = String #14 // abc
#3 = Class #15 // Test
#4 = Class #16 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 main
#10 = Utf8 ([Ljava/lang/String;)V
#11 = Utf8 SourceFile
#12 = Utf8 Test.java
#13 = NameAndType #5:#6 // "<init>":()V
#14 = Utf8 abc
#15 = Utf8 Test
#16 = Utf8 java/lang/Object
所以你错了。一个String
已创建——"abc"
并在运行时放入String
池中。
此处的编译器执行了常量折叠并将编译时常量表达式简化"a" + "b" + "c"
为"abc"
. 如果使用标志进行编译,则可以看到这一点,该-XD-printflat
标志显示了编译器编译为字节码的实际源代码:
public static void main(final String[] args) {
String temp = "abc";
}
如果您想查看实际的String
串联,则必须使用不是编译时常量的操作数,例如变量:
public static void main(final String[] args) {
String a = "a";
String b = "b";
String c = "c";
String temp = a + b + c;
}
编译为:
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String a
2: astore_1
3: ldc #3 // String b
5: astore_2
6: ldc #4 // String c
8: astore_3
9: new #5 // class java/lang/StringBuilder
12: dup
13: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
16: aload_1
17: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: aload_2
21: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: aload_3
25: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore 4
33: return