Nie do końca.
Po pierwsze, istnieje niewielka różnica w semantyce. Jeśli atak null, to a.concat(b)rzuca a, NullPointerExceptionale a+=bpotraktuje oryginalną wartość atak, jakby była null. Ponadto concat()metoda akceptuje tylko Stringwartoś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 += bjest odpowiednikiem
a = new StringBuilder()
.append(a)
.append(b)
.toString();
concatMetoda powinna być szybsza. Jednak przy większej liczbie ciągów StringBuildermetoda wygrywa, przynajmniej pod względem wydajności.
Kod źródłowy Stringi 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. javacnadal 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 StringBufferkod 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 .