El operador += es un ejemplo de operador que nunca se debe utilizar, debido a como esta implementado, veamos este codigo.
1: package test; 2: 3: public class StringTest { 4: public static void main(String[] args) { 5: String x = "cadena1"; 6: x += "cadena2"; 7: System.out.println(x); 8: } 9: } 10:
Si de compilamos el codigo java resultante (el archivo .class) con el comando "javap -c", obtenemos lo siguiente:
Compiled from "StringTest.java" public class test.StringTest extends java.lang.Object{ public test.StringTest(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16; //String cadena1 2: astore_1 3: new #18; //class java/lang/StringBuilder 6: dup 7: aload_1 8: invokestatic #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 11: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 14: ldc #29; //String cadena2 16: invokevirtual #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_1 23: getstatic #39; //Field java/lang/System.out:Ljava/io/PrintStream; 26: aload_1 27: invokevirtual #45; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return }
El codigo equivalente, para generar el mismo resultado, pero utilizando explicitamente la clase StringBuilder y la funcion valueOf, es el siguiente:
1: package test; 2: 3: public class StringTest2 { 4: public static void main(String[] args) { 5: String x = "cadena1"; 6: x = new StringBuilder(String.valueOf(x)).append("cadena2").toString(); 7: System.out.println(x); 8: } 9: } 10:
Pero que ocurre cuando se mete la operacion += dentro de un loop? Como en el siguiente codigo:
01: package test; 02: 03: public class StringTest3 { 04: public static void main(String[] args) { 05: String x = "cadena1"; 06: for (int i = 0; i < 10; i++) { 07: x += "cadena2"; 08: } 09: } 10: } 11:
Al decompilar, se genera el siguiente codigo:
Compiled from "StringTest3.java" public class test.StringTest3 extends java.lang.Object{ public test.StringTest3(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16; //String cadena1 2: astore_1 3: iconst_0 4: istore_2 5: goto 31 8: new #18; //class java/lang/StringBuilder 11: dup 12: aload_1 13: invokestatic #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 19: ldc #29; //String cadena2 21: invokevirtual #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_1 28: iinc 2, 1 31: iload_2 32: bipush 10 34: if_icmplt 8 37: return }
Es decir, el codigo equivalente es el siguiente:
01: package test; 02: 03: public class StringTest4 { 04: public static void main(String[] args) { 05: String x = "cadena1"; 06: for (int i = 0; i < 10; i++) { 07: x = new StringBuilder(String.valueOf(x)).append("cadena2").toString(); 08: } 09: } 10: } 11:
Como se puede observar, en cada iteracion, se construye un nuevo objeto StringBuilder, con el resultado de ejecutar la funcion valueOf, que recibe como parametro la variable x, posterior mente, se agrega la cadena que "cadena2" y finalmente, se convierte en una cadena nueva, la cual se asigna a la variable x.
Derivado de esto es destacable notar que este codigo es ineficiente, en la mayoria de las situaciones, particularmente cuando se emplea dentro de loops.
Sin embargo, cuando se emplea en conjunto con el operador +, puede eficiente, pero solo si se conoce exactamente la cantidad de elemenos implicados en la operacion. Como en el siguiente ejemplo:
01: package test; 02: 03: public class StringTest5 { 04: public static void main(String[] args) { 05: String x = "cadena1"; 06: String y = "auxiliar"; 07: x += "cadena2" + y; 08: System.out.println(x); 09: } 10: } 11:
Al de compilar se obtiene lo siguiente:
Compiled from "StringTest5.java" public class test.StringTest5 extends java.lang.Object{ public test.StringTest5(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16; //String cadena1 2: astore_1 3: ldc #18; //String auxiliar 5: astore_2 6: new #20; //class java/lang/StringBuilder 9: dup 10: aload_1 11: invokestatic #22; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 14: invokespecial #28; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 17: ldc #31; //String cadena2 19: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: aload_2 23: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 26: invokevirtual #37; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: astore_1 30: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream; 33: aload_1 34: invokevirtual #47; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 37: return }
El codigo equivalente, es el siguiente:
01: package test; 02: 03: public class StringTest6 { 04: public static void main(String[] args) { 05: String x = "cadena1"; 06: String y = "auxiliar"; 07: x = new StringBuilder(String.valueOf(x)).append("cadena2").append(y) 08: .toString(); 09: System.out.println(x); 10: } 11: } 12:
Lo cual es eficiente para en terminos de uso de los objetos creados.
No hay comentarios.:
Publicar un comentario