2012-05-04 9 views
5

Estaba teniendo una discusión sobre el uso de String sy StringBuffer s en Java. ¿Cuántos objetos se crean en cada uno de estos dos ejemplos?Cuantos objetos se crean

Ex 1:

String s = "a"; 
s = s + "b"; 
s = s + "c";   

Ex 2:

StringBuilder sb = new StringBuilder("a"); 
sb.append("b"); 
sb.append("c"); 

En mi opinión, Ex 1 y 5 creará Ex 2 creará 4 objetos.

+2

El primer ejemplo creará 1 objeto ya que el compilador puede optimizarlo. –

+0

javac optimizará eso? –

+1

El ejemplo 1 genera esto: 'String s =" a "; s = (nuevo StringBuilder (String.valueOf (s))). Append ("b"). ToString(); s = (new StringBuilder (String.valueOf (s))). Append ("c"). ToString(); System.err.println (s); '. Parece que javac no está optimizando eso (al menos en Java 6) –

Respuesta

4

Puede determinar la respuesta analizando el bytecode java (use javap -c). El ejemplo 1 crea dos objetos StringBuilder (vea la línea 4) y dos objetos String (vea la línea 7), mientras que el ejemplo 2 crea un objeto StringBuilder (vea la línea 2).

Tenga en cuenta que también debe tener en cuenta los objetos char[] (ya que las matrices son objetos en Java). Los objetos String y StringBuilder se implementan utilizando un subyacente char[]. Por lo tanto, el ejemplo 1 crea ocho objetos y el ejemplo 2 crea dos objetos.

Ejemplo 1:

public static void main(java.lang.String[]); 
    Code: 
    0: ldc    #2; //String a 
    2: astore_1 
    3: new    #3; //class java/lang/StringBuilder 
    6: dup 
    7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 
    10: aload_1 
    11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    14: ldc    #6; //String b 
    16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    22: astore_1 
    23: new    #3; //class java/lang/StringBuilder 
    26: dup 
    27: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 
    30: aload_1 
    31: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    34: ldc    #8; //String c 
    36: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    39: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    42: astore_1 
    43: return 
} 

Ejemplo 2:

public static void main(java.lang.String[]); 
    Code: 
    0: new    #2; //class java/lang/StringBuilder 
    3: dup 
    4: ldc    #3; //String a 
    6: invokespecial #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    9: astore_1 
    10: aload_1 
    11: ldc    #5; //String b 
    13: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: pop 
    17: aload_1 
    18: ldc    #7; //String c 
    20: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    23: pop 
    24: return 
} 
+0

Tengo una pequeña duda. , los documentos de Oracle aquí http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html dicen esto acerca de append: "public StringBuilder append (Object obj) Añade la representación de cadena del Argumento del objeto El efecto general es exactamente como si el argumento se convirtiera en una cadena mediante el método String.valueOf (Object), y los caracteres de esa cadena se anexaron a esta secuencia de caracteres. " Eso no significa que los objetos serán creados para literales de Cadena. –

5

En cuanto a los objetos creados:

Ejemplo 1 crea 8 objetos:

String s = "a"; // No object created 
s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String) 
s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String) 

Ejemplo 2 crea 2 alojamiento:

StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB) 
sb.append("b"); // 0 
sb.append("c"); // 0 

Para ser justos, no sabía que el nuevo char [] realmente creó un objeto en Java (pero yo sabía que fueron creados). Gracias a aix por señalar eso.

+0

Downvoter ¿le importaría dar su opinión? –

+0

Habría podido ejecutar el procedimiento de prueba en otra versión de JDK y obtener resultados diferentes. –

5

He usado un generador de perfiles de memoria para obtener las cantidades exactas.

En mi máquina, el primer ejemplo crea objetos: 8

String s = "a"; 
s = s + "b"; 
s = s + "c"; 
  • dos objetos de tipo String;
  • dos objetos del tipo StringBuilder;
  • cuatro objetos del tipo char[].

Por otro lado, el segundo ejemplo:

StringBuffer sb = new StringBuffer("a"); 
sb.append("b"); 
sb.append("c"); 

crea 2 objetos:

  • un objeto de tipo StringBuilder;
  • un objeto del tipo char[].

Esto es usando JDK 1.6u30.

P.S. Para que la comparación sea justa, probablemente deba llamar al sb.toString() al final del segundo ejemplo.

+0

es esta máquina/compilador-dependiente? –

+0

@AlexLockwood: Probablemente dependiente de JDK hasta cierto punto, aunque me sorprendería bastante si hubiera mucha variabilidad entre los JDK recientes. – NPE

+0

Parece bastante tonto distinguir entre una abstracción 'char []' y 'String' en un lenguaje de alto nivel como Java: P. Pero estoy de acuerdo en que es correcto hacerlo (no tonto de tu parte ... simplemente tonto en un tipo de ejemplo estúpido como este). –

-1

La respuesta está ligada a implementaciones específicas del lenguaje (compilador y bibliotecas de tiempo de ejecución). Incluso a la presencia de opciones de optimización específicas o no. Y, por supuesto, la versión de la implementación (e, implícitamente, la JLS con la que cumple). Por lo tanto, es mejor hablar en términos de mínimos y máximos. De hecho, este ejercicio da una mejor

Para Ex1, el número mínimo de objetos es 1 (el compilador se da cuenta de que solo hay constantes involucradas y produce solo código para String s= "abc" ;). El máximo podría ser cualquier cosa, dependiendo de la implementación, pero una estimación razonable es 8 (también se da en otra respuesta como el número producido por cierta configuración).

Para Ex2, el número mínimo de objetos es 2. El compilador no tiene forma de saber si hemos reemplazado StringBuilder con una versión personalizada con semántica diferente, por lo que no se optimizará. El máximo podría ser alrededor de 6, para una implementación de StringBuilder extremadamente conservadora de la memoria que expande una matriz de respaldo char[] un carácter a la vez, pero en la mayoría de los casos será 2 también.

+0

El compilador 'produce código para 'String s =" abc ";'', pero esto no crea un objeto cuando se ejecuta, por lo que el mínimo es en realidad cero. – EJP

Cuestiones relacionadas