Không, không hẳn.
Thứ nhất, có một chút khác biệt về ngữ nghĩa. Nếu a
là null
, sau đó a.concat(b)
ném một NullPointerException
nhưng a+=b
sẽ coi giá trị ban đầu a
như thể nó là null
. Hơn nữa, concat()
phương thức chỉ chấp nhận String
các giá trị trong khi +
toán tử sẽ âm thầm chuyển đổi đối số thành Chuỗi (sử dụng toString()
phương thức cho các đối tượng). Vì vậy, concat()
phương pháp nghiêm ngặt hơn trong những gì nó chấp nhận.
Để nhìn dưới mui xe, hãy viết một lớp đơn giản với a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
Bây giờ tháo rời với javap -c
(bao gồm trong Sun JDK). Bạn sẽ thấy một danh sách bao gồm:
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
Vì vậy, a += b
là tương đương với
a = new StringBuilder()
.append(a)
.append(b)
.toString();
Các concat
phương pháp cần được nhanh hơn. Tuy nhiên, với nhiều chuỗi hơn, StringBuilder
phương thức sẽ thắng, ít nhất là về hiệu suất.
Mã nguồn của String
và StringBuilder
(và lớp cơ sở riêng của gói) có sẵn trong src.zip của Sun JDK. Bạn có thể thấy rằng bạn đang xây dựng một mảng char (thay đổi kích thước khi cần thiết) và sau đó ném nó đi khi bạn tạo bản cuối cùngString
. Trong thực tế phân bổ bộ nhớ là nhanh đáng ngạc nhiên.
Cập nhật: Như chú thích của Pawel Adamski, hiệu suất đã thay đổi trong HotSpot gần đây. javac
vẫn tạo ra chính xác cùng một mã, nhưng trình biên dịch mã byte gian lận. Thử nghiệm đơn giản hoàn toàn thất bại vì toàn bộ phần mã bị vứt đi. Tóm tắt System.identityHashCode
(không String.hashCode
) cho thấy StringBuffer
mã có một lợi thế nhỏ. Có thể thay đổi khi bản cập nhật tiếp theo được phát hành hoặc nếu bạn sử dụng một JVM khác. Từ @lukasinger , một danh sách các nội tại JVM của HotSpot .