Поскольку "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;
Если бы у вас были две строковые переменные, эта оптимизация не сработала бы:
Следующий фрагмент ...
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
. Полученный String
этого временного StringBuilder
затем выбирается в строке 32 и добавляется к исходному StringBuilder
в строке 35.
(Байт-код был сгенерирован командой javap
, которая является частью JDK. Попробуйте, это действительно просто!)