No, no del todo.
En primer lugar, hay una ligera diferencia en la semántica. Si a
es así null
, a.concat(b)
arroja un NullPointerException
pero a+=b
tratará el valor original de a
como si lo fuera null
. Además, el concat()
método solo acepta String
valores, 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 += b
es el equivalente de
a = new StringBuilder()
.append(a)
.append(b)
.toString();
El concat
método debería ser más rápido. Sin embargo, con más cadenas, el StringBuilder
método gana, al menos en términos de rendimiento.
El código fuente de String
y 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. javac
todaví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 StringBuffer
có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 .