Cara "lama" menghasilkan banyak StringBuilder
operasi yang berorientasi. Pertimbangkan program ini:
public class Example {
public static void main(String[] args)
{
String result = args[0] + "-" + args[1] + "-" + args[2];
System.out.println(result);
}
}
Jika kita mengkompilasinya dengan JDK 8 atau sebelumnya dan kemudian menggunakan javap -c Example
untuk melihat bytecode, kita akan melihat sesuatu seperti ini:
Contoh kelas publik {
Contoh publik ();
Kode:
0: aload_0
1: invokespecial # 1 // Metode java / lang / Object. "<init>" :() V
4: kembali
public static void main (java.lang.String []);
Kode:
0: baru # 2 // kelas java / lang / StringBuilder
3: dup
4: invokespecial # 3 // Metode java / lang / StringBuilder. "<init>" :() V
7: aload_0
8: iconst_0
9: aaload
10: invokevirtual # 4 // Metode java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
13: ldc # 5 // String -
15: invokevirtual # 4 // Metode java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
18: aload_0
19: iconst_1
20: aaload
21: invokevirtual # 4 // Metode java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
24: ldc # 5 // String -
26: invokevirtual # 4 // Metode java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
29: aload_0
30: iconst_2
31: aaload
32: invokevirtual # 4 // Metode java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
35: invokevirtual # 6 // Metode java / lang / StringBuilder.toString :() Ljava / lang / String;
38: astore_1
39: getstatic # 7 // Bidang java / lang / System.out: Ljava / io / PrintStream;
42: aload_1
43: invokevirtual # 8 // Metode java / io / PrintStream.println: (Ljava / lang / String;) V
46: kembali
}
Seperti yang Anda lihat, ini membuat StringBuilder
dan menggunakan append
. Ini terkenal cukup tidak efisien karena kapasitas default buffer internal StringBuilder
hanya 16 karakter, dan tidak ada cara bagi compiler untuk mengetahui mengalokasikan lebih banyak, sehingga akhirnya harus mengalokasikan ulang. Ini juga banyak panggilan metode. (Perhatikan bahwa JVM terkadang dapat mendeteksi dan menulis ulang pola panggilan ini untuk membuatnya lebih efisien.)
Mari kita lihat apa yang dihasilkan Java 9:
Contoh kelas publik {
Contoh publik ();
Kode:
0: aload_0
1: invokespecial # 1 // Metode java / lang / Object. "<init>" :() V
4: kembali
public static void main (java.lang.String []);
Kode:
0: aload_0
1: iconst_0
2: aaload
3: aload_0
4: iconst_1
5: aaload
6: aload_0
7: iconst_2
8: aaload
9: invokedynamic # 2, 0 // InvokeDynamic # 0: makeConcatWithConstants: (Ljava / lang / String; Ljava / lang / String; Ljava / lang / String;) Ljava / lang / String;
14: astore_1
15: getstatic # 3 // Bidang java / lang / System.out: Ljava / io / PrintStream;
18: aload_1
19: invokevirtual # 4 // Metode java / io / PrintStream.println: (Ljava / lang / String;) V
22: kembali
}
Ya ampun, tapi itu lebih pendek. :-) Itu membuat satu panggilan ke makeConcatWithConstants
dari StringConcatFactory
, yang mengatakan ini di Javadoc-nya:
Metode untuk memfasilitasi pembuatan metode penggabungan String, yang dapat digunakan untuk secara efisien menggabungkan sejumlah argumen dari tipe yang diketahui, kemungkinan setelah adaptasi tipe dan evaluasi parsial argumen. Metode ini biasanya digunakan sebagai metode bootstrap untuk invokedynamic
situs panggilan, untuk mendukung fitur penggabungan string dari Bahasa Pemrograman Java.