วิธี "เก่า" จะแสดงStringBuilder
การดำเนินการที่มีพื้นฐาน พิจารณาโปรแกรมนี้:
public class Example {
public static void main(String[] args)
{
String result = args[0] + "-" + args[1] + "-" + args[2];
System.out.println(result);
}
}
หากเรารวบรวมสิ่งนั้นด้วย JDK 8 หรือก่อนหน้าแล้วใช้javap -c Example
เพื่อดู bytecode เราจะเห็นสิ่งนี้:
public class ตัวอย่าง {
ตัวอย่างสาธารณะ ();
รหัส:
0: aload_0
1: invokespecial # 1 // วิธี java / lang / Object. "<init>" :() V
4: กลับ
โมฆะคงที่สาธารณะหลัก (java.lang.String []);
รหัส:
0: ใหม่ # 2 // คลาส java / lang / StringBuilder
3: dup
4: invokespecial # 3 // Method java / lang / StringBuilder. "<init>" :() V
7: aload_0
8: iconst_0
9: aaload
10: invokevirtual # 4 // วิธี java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
13: ldc # 5 // สตริง -
15: invokevirtual # 4 // วิธี java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
18: aload_0
19: iconst_1
20: aaload
21: invokevirtual # 4 // วิธี java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
24: ldc # 5 // สตริง -
26: invokevirtual # 4 // วิธี java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
29: aload_0
30: iconst_2
31: aaload
32: invokevirtual # 4 // วิธี java / lang / StringBuilder.append: (Ljava / lang / String;) Ljava / lang / StringBuilder;
35: invokevirtual # 6 // วิธี java / lang / StringBuilder.toString :() Ljava / lang / String;
38: astore_1
39: getstatic # 7 // ฟิลด์ java / lang / System.out: Ljava / io / PrintStream;
42: aload_1
43: invokevirtual # 8 // วิธี java / io / PrintStream.println: (Ljava / lang / String;) V
46: กลับ
}
อย่างที่คุณเห็นมันสร้างStringBuilder
และใช้append
. สิ่งนี้มีชื่อเสียงค่อนข้างไม่มีประสิทธิภาพเนื่องจากความจุเริ่มต้นของบัฟเฟอร์ในตัวStringBuilder
มีเพียง 16 ตัวอักษรและไม่มีทางที่คอมไพเลอร์จะรู้ว่าจะจัดสรรเพิ่มเติมล่วงหน้าได้ดังนั้นจึงต้องจัดสรรใหม่ นอกจากนี้ยังมีการเรียกวิธีการมากมาย (โปรดทราบว่าบางครั้ง JVM สามารถตรวจจับและเขียนรูปแบบการโทรเหล่านี้ใหม่เพื่อให้มีประสิทธิภาพมากขึ้น)
มาดูกันว่า Java 9 สร้างอะไรบ้าง:
public class ตัวอย่าง {
ตัวอย่างสาธารณะ ();
รหัส:
0: aload_0
1: invokespecial # 1 // วิธี java / lang / Object. "<init>" :() V
4: กลับ
โมฆะคงที่สาธารณะหลัก (java.lang.String []);
รหัส:
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 // ฟิลด์ java / lang / System.out: Ljava / io / PrintStream;
18: aload_1
19: invokevirtual # 4 // วิธี java / io / PrintStream.println: (Ljava / lang / String;) V
22: กลับ
}
โอ้ แต่มันสั้นกว่า :-) มันทำให้สายเดียวที่จะmakeConcatWithConstants
จากStringConcatFactory
ที่ว่านี้ใน Javadoc ที่:
วิธีการอำนวยความสะดวกในการสร้างวิธีการต่อสายอักขระที่สามารถใช้เพื่อเชื่อมอาร์กิวเมนต์ที่เป็นที่รู้จักจำนวนมากอย่างมีประสิทธิภาพซึ่งอาจเป็นไปได้หลังจากการปรับประเภทและการประเมินอาร์กิวเมนต์บางส่วน โดยทั่วไปวิธีการเหล่านี้ใช้เป็นวิธีการบูตสำหรับinvokedynamic
ไซต์การโทรเพื่อสนับสนุนคุณลักษณะการต่อสายอักขระของภาษาการเขียนโปรแกรม Java