ไม่เลย
ประการแรกมีความแตกต่างเล็กน้อยในความหมาย ถ้าaเป็นnullแล้วa.concat(b)พ่นNullPointerExceptionแต่a+=bจะรักษาค่าเดิมของราวกับว่ามันเป็นa nullนอกจากนี้concat()วิธีการยอมรับเฉพาะStringค่าในขณะที่+ผู้ประกอบการจะแปลงอาร์กิวเมนต์เป็นเงียบ ๆ (ใช้toString()วิธีการสำหรับวัตถุ) ดังนั้นconcat()วิธีการที่เข้มงวดมากขึ้นในสิ่งที่มันยอมรับ
เพื่อดูภายใต้ประทุนเขียนชั้นเรียนง่ายๆด้วย a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
ตอนนี้ถอดแยกชิ้นส่วนด้วยjavap -c(รวมอยู่ใน Sun JDK) คุณควรเห็นรายชื่อรวมถึง:
java.lang.String cat(java.lang.String, java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/ String;
18: astore_1
19: aload_1
20: areturn
ดังนั้นจึงa += bเท่ากับ
a = new StringBuilder()
.append(a)
.append(b)
.toString();
concatวิธีการควรจะเร็ว อย่างไรก็ตามด้วยStringBuilderวิธีการจำนวนมากที่ชนะอย่างน้อยในแง่ของประสิทธิภาพ
ซอร์สโค้ดของStringและStringBuilder(และคลาสฐานแพ็กเกจส่วนตัว) มีอยู่ใน src.zip ของ Sun JDK คุณจะเห็นว่าคุณกำลังสร้างขึ้นแถวถ่าน (ปรับขนาดได้ตามความจำเป็น) Stringแล้วทิ้งมันไปเมื่อคุณสร้างในขั้นตอนสุดท้าย ในทางปฏิบัติการจัดสรรหน่วยความจำนั้นรวดเร็วอย่างน่าประหลาดใจ
อัปเดต:ในฐานะที่เป็นบันทึกของ Pawel Adamski ประสิทธิภาพได้เปลี่ยนไปใน HotSpot ล่าสุด javacยังคงสร้างรหัสเดียวกันทั้งหมด แต่สูตรคอมไพเลอร์ bytecode การทดสอบอย่างง่ายล้มเหลวโดยสิ้นเชิงเนื่องจากรหัสทั้งหมดถูกโยนทิ้งไป การรวมSystem.identityHashCode(ไม่String.hashCode) แสดงStringBufferรหัสมีข้อได้เปรียบเล็กน้อย อาจมีการเปลี่ยนแปลงเมื่อมีการเปิดตัวอัพเดตครั้งถัดไปหรือหากคุณใช้ JVM อื่น จาก@lukaseder , รายการ intrinsics