No, no del todo.
En primer lugar, hay una ligera diferencia en la semántica. Si aes así null, a.concat(b)arroja un NullPointerExceptionpero a+=btratará el valor original de acomo si lo fuera null. Además, el concat()método solo acepta Stringvalores, mientras que el +operador convertirá silenciosamente el argumento en una Cadena (utilizando el toString()método para objetos). Entonces, el concat()método es más estricto en lo que acepta.
Para mirar debajo del capó, escriba una clase simple con a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
Ahora desmonte con javap -c(incluido en Sun JDK). Debería ver una lista que incluye:
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
Entonces, a += bes el equivalente de
a = new StringBuilder()
.append(a)
.append(b)
.toString();
El concatmétodo debería ser más rápido. Sin embargo, con más cadenas, el StringBuildermétodo gana, al menos en términos de rendimiento.
El código fuente de Stringy StringBuilder(y su clase base de paquete privado) está disponible en src.zip del Sun JDK. Puede ver que está creando una matriz de caracteres (redimensionando según sea necesario) y luego tirándola cuando cree la final String. En la práctica, la asignación de memoria es sorprendentemente rápida.
Actualización: como señala Pawel Adamski, el rendimiento ha cambiado en HotSpot más reciente. javactodavía produce exactamente el mismo código, pero el compilador de bytecode hace trampa. Las pruebas simples fallan por completo porque se desecha todo el cuerpo del código. La suma System.identityHashCode(no String.hashCode) muestra que el StringBuffercódigo tiene una ligera ventaja. Sujeto a cambios cuando se lance la próxima actualización, o si usa una JVM diferente. De @lukaseder , una lista de intrínsecos de HotSpot JVM .