基于这里公认的答案,我希望能够开始看看引擎盖下的东西。
让我们看一下将字符串与字符连接时生成的字节码:
String str1 = "a" + "test";
String str2 = 'a' + "test";
0: ldc #2 // String atest
2: astore_1
3: ldc #2 // String atest
5: astore_2
如您所见,没有区别,编译器会将其转换为相同的字节码。
现在,让我们看一下将字符连接到 String 变量时生成的字节码。
String str1 = "a" + str3; //str3 is a String
String str2 = 'a' + str3;
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String a
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_2
23: new #3 // class java/lang/StringBuilder
26: dup
27: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
30: bipush 97
32: invokevirtual #8 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
35: aload_1
36: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
39: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
如您所见,有一点不同。
10: ldc #5 // String a
ldc
将常量#index从常量池(字符串、整型或浮点型)推送到堆栈上。
因此,如果您直接与变量连接,则连接字符将生成较少的字节码,这就是底层的内容。
现在,对于性能问题,这不会代表任何显著的性能差异,因为 JIT 编译器优化了大多数临时对象,除非您在运行程序时指定使用 禁用 JIT 编译器。-Djava.compiler=NONE