No, non del tutto.
Innanzitutto, c'è una leggera differenza nella semantica. Se a
è null
, quindi a.concat(b)
genera un NullPointerException
ma a+=b
tratterà il valore originale di a
come se fosse null
. Inoltre, il concat()
metodo accetta solo String
valori mentre l' +
operatore convertirà silenziosamente l'argomento in una stringa (usando il toString()
metodo per gli oggetti). Così laconcat()
metodo è più rigoroso in ciò che accetta.
Per guardare sotto il cofano, scrivi una lezione semplice con a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
Ora smonta con javap -c
(incluso nel Sun JDK). Dovresti vedere un elenco che include:
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
Quindi, a += b
è l'equivalente di
a = new StringBuilder()
.append(a)
.append(b)
.toString();
Il concat
metodo dovrebbe essere più veloce. Tuttavia, con più stringhe il StringBuilder
metodo vince, almeno in termini di prestazioni.
Il codice sorgente di String
e StringBuilder
(e la sua classe base privata pacchetto) è disponibile in src.zip di Sun JDK. Puoi vedere che stai creando un array di caratteri (ridimensionandolo se necessario) e poi lo butti via quando crei il finale String
. In pratica, l'allocazione della memoria è sorprendentemente veloce.
Aggiornamento: come osserva Pawel Adamski, le prestazioni sono cambiate negli HotSpot più recenti. javac
produce ancora esattamente lo stesso codice, ma il compilatore bytecode tradisce. I test semplici falliscono del tutto perché l'intero corpo del codice viene eliminato. La somma System.identityHashCode
(non String.hashCode
) mostra che il StringBuffer
codice ha un leggero vantaggio. Soggetto a modifiche quando viene rilasciato il prossimo aggiornamento o se si utilizza una JVM diversa. Da @lukaseder , un elenco di elementi intrinseci di HotSpot JVM .