Nie do końca.
Po pierwsze, istnieje niewielka różnica w semantyce. Jeśli a
tak null
, to a.concat(b)
rzuca a, NullPointerException
ale a+=b
potraktuje oryginalną wartość a
tak, jakby była null
. Ponadto concat()
metoda akceptuje tylko String
wartości, podczas gdy +
operator po cichu przekształci argument na ciąg znaków (używając toString()
metody dla obiektów). Zatem concat()
metoda jest bardziej rygorystyczna pod względem tego, co akceptuje.
Aby zajrzeć pod maską, napisz prostą lekcję a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
Teraz zdemontuj za pomocą javap -c
(zawartego w Sun JDK). Powinieneś zobaczyć listę zawierającą:
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
Więc a += b
jest odpowiednikiem
a = new StringBuilder()
.append(a)
.append(b)
.toString();
concat
Metoda powinna być szybsza. Jednak przy większej liczbie ciągów StringBuilder
metoda wygrywa, przynajmniej pod względem wydajności.
Kod źródłowy String
i StringBuilder
(i jego podstawowa klasa pakietu) jest dostępny w src.zip Sun JDK. Możesz zobaczyć, że budujesz tablicę char (zmieniając rozmiar w razie potrzeby), a następnie wyrzucasz ją podczas tworzenia finału String
. W praktyce przydzielanie pamięci jest zaskakująco szybkie.
Aktualizacja: Jak zauważa Paweł Adamski, wydajność zmieniła się w najnowszym HotSpot. javac
nadal generuje dokładnie ten sam kod, ale kompilator kompilatora bajtów oszukuje. Proste testowanie całkowicie kończy się niepowodzeniem, ponieważ cały kod jest wyrzucany. Sumowanie System.identityHashCode
(nie String.hashCode
) pokazuje, że StringBuffer
kod ma niewielką przewagę. Zastrzega się możliwość zmian po wydaniu kolejnej aktualizacji lub w przypadku korzystania z innej maszyny JVM. Od @lukaseder , listy intrinsics HotSpot JVM .