由于"b" + "u" 是一个在编译时求值的表达式,它会被编译,就像你有"bu" 一样。
0: new #2; //class StringBuilder
3: dup
4: ldc #3; //String bu
6: invokespecial #4; //Method StringBuilder."<init>":(String;)V
9: astore_1
10: aload_1
11: ldc #3; //String bu
13: invokevirtual #5; // StringBuilder.append:(String;)LStringBuilder;
另一方面,如果您有两个字符串变量,则此优化不会生效:
下面的sn-p...
StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";
sb.append(b + u);
...编译为:
0: new #2; //class StringBuilder
3: dup
4: ldc #3; //String bu
6: invokespecial #4; //Method StringBuilder."<init>":(String;)V
9: astore_1
10: ldc #5; //String b
12: astore_2
13: ldc #6; //String u
15: astore_3
16: aload_1
17: new #2; //class StringBuilder
20: dup
21: invokespecial #7; //Method StringBuilder."<init>":()V
24: aload_2
25: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
28: aload_3
29: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
32: invokevirtual #9; //Method StringBuilder.toString:()String;
35: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
即类似于
StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";
StringBuilder temp = new StringBuilder();
temp.append(b);
temp.append(b);
String result = temp.toString();
sb.append(result);
正如您在第 17-21 行中看到的那样,创建了一个额外的 StringBuilder 用于连接 a 和 b。然后在第 32 行获取此临时 StringBuilder 的结果 String,并在第 35 行附加到原始 StringBuilder。
(字节码是由JDK中的javap命令生成的。试试看,真的很简单!)