"Eski" yöntem, bir dizi StringBuilder
odaklı işlem üretir . Bu programı düşünün:
public class Example {
public static void main(String[] args)
{
String result = args[0] + "-" + args[1] + "-" + args[2];
System.out.println(result);
}
}
Bunu JDK 8 veya öncesi ile derlersek ve sonra javap -c Example
bayt kodunu görmek için kullanırsak , şuna benzer bir şey görürüz:
public class Örneği {
genel Örnek ();
Kod:
0: aload_0
1: özel # 1 çağrısı // Yöntem java / lang / Object. "<init>" :() V
4: dönüş
public static void main (java.lang.String []);
Kod:
0: yeni # 2 // sınıf java / lang / StringBuilder
3: çift
4: özel # 3'ü çağırın // Yöntem java / lang / StringBuilder. "<init>" :() V
7: aload_0
8: iconst_0
9: aaload
10: invokevirtual # 4 // Yöntem java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
13: ldc # 5 // Dize -
15: invokevirtual # 4 // Yöntem java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
18: aload_0
19: iconst_1
20: aaload
21: invokevirtual # 4 // Yöntem java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
24: ldc # 5 // Dize -
26: invokevirtual # 4 // Yöntem java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
29: aload_0
30: iconst_2
31: aaload
32: invokevirtual # 4 // Yöntem java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
35: invokevirtual # 6 // Yöntem java / lang / StringBuilder.toString :() Ljava / lang / String;
38: astore_1
39: getstatic # 7 // Alan java / lang / System.out: Ljava / io / PrintStream;
42: aload_1
43: invokevirtual # 8 // Yöntem java / io / PrintStream.println: (Ljava / lang / String;) V
46: dönüş
}
Gördüğünüz gibi, bir yaratır StringBuilder
ve kullanır append
. Bu, yerleşik arabelleğin varsayılan kapasitesi StringBuilder
yalnızca 16 karakter olduğu için oldukça verimsizdir ve derleyicinin önceden daha fazla ayırmayı bilmesinin bir yolu yoktur , bu nedenle yeniden tahsis etmek zorunda kalır. Aynı zamanda bir sürü yöntem çağrısı. (JVM'nin bazen bu çağrı kalıplarını daha verimli hale getirmek için algılayıp yeniden yazabileceğini unutmayın .)
Java 9'un ne ürettiğine bakalım:
public class Örneği {
genel Örnek ();
Kod:
0: aload_0
1: özel # 1 çağrısı // Yöntem java / lang / Object. "<init>" :() V
4: dönüş
public static void main (java.lang.String []);
Kod:
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 // Alan java / lang / System.out: Ljava / io / PrintStream;
18: aload_1
19: invokevirtual # 4 // Yöntem java / io / PrintStream.println: (Ljava / lang / String;) V
22: dönüş
}
Aman tanrım ama bu daha kısa. :-) Bu tek bir çağrı yapar makeConcatWithConstants
dan StringConcatFactory
onun Javadoc bu diyor:
Muhtemelen tip uyarlamasından ve bağımsız değişkenlerin kısmi değerlendirmesinden sonra, bilinen türde bilinen sayıda bağımsız değişkeni verimli bir şekilde birleştirmek için kullanılabilen Dize birleştirme yöntemlerinin oluşturulmasını kolaylaştıran yöntemler. Bu yöntemler tipik olarak , Java Programlama Dilinin dizi birleştirme özelliğini desteklemek için arama siteleri için önyükleme yöntemleri olarak kullanılır .invokedynamic