2010-09-02 16 views
7

De acuerdo con la herramienta PMD, la siguiente es una mala práctica:Agregue una cadena vacía vs toString - ¿por qué es malo?

String s = "" + 123; // bad 
String t = Integer.toString(456); // ok 


This is an inefficient way to convert any type to a `String`. 

¿Por qué es una mala cosa que hacer?

+0

Aparentemente, para constantes (estáticas/finales) "" + 123 es más eficiente. Para otros valores, usar toString es más eficiente. – corgrath

+0

"Estático/final" puede ser engañoso. Un campo debe ser _both_ estático y final para considerarse una constante, y solo para primitivas y cadenas. (Las variables locales nunca se consideran constantes.) –

+0

posible duplicado de [¿Es la conversión a String usando ("" + ) mala práctica?] (Http://stackoverflow.com/questions/1572708/is-conversion-to-string- using-int-value-bad-practice) – McDowell

Respuesta

10
String s = "" + 123; // bad  
String t = Integer.toString(456); 

se compilará a:

String s = "123"; 
String t = Integer.toString(456); 

así: "" 123 es obvia poco mejor! comprobado con JAD

public static void main(String args[]) 
{ 
// 0 0:ldc1   #16 <String "123"> 
// 1 2:astore_1 
// 2 3:sipush   456 
// 3 6:invokestatic #18 <Method String Integer.toString(int)> 
// 4 9:astore_2 
// 5 10:getstatic  #24 <Field PrintStream System.out> 
// 6 13:new    #30 <Class StringBuilder> 
// 7 16:dup 
// 8 17:aload_1 
// 9 18:invokestatic #32 <Method String String.valueOf(Object)> 
// 10 21:invokespecial #38 <Method void StringBuilder(String)> 
// 11 24:aload_2 
// 12 25:invokevirtual #41 <Method StringBuilder StringBuilder.append(String)> 
// 13 28:invokevirtual #45 <Method String StringBuilder.toString()> 
// 14 31:invokevirtual #48 <Method void PrintStream.println(String)> 
// 15 34:return 
} 

EDIT:

Para valores no constantes:

int i = 123; 
String s = (new StringBuilder()).append(i).toString(); 
String t = Integer.toString(i); 
System.out.println((new StringBuilder(String.valueOf(s))).append(t).toString()); 

    public static void main(String args[]) 
    { 
    // 0 0:bipush   123 
    // 1 2:istore_1 
    // 2 3:new    #16 <Class StringBuilder> 
    // 3 6:dup 
    // 4 7:invokespecial #18 <Method void StringBuilder()> 
    // 5 10:iload_1 
    // 6 11:invokevirtual #19 <Method StringBuilder StringBuilder.append(int)> 
    // 7 14:invokevirtual #23 <Method String StringBuilder.toString()> 
    // 8 17:astore_2 
    // 9 18:iload_1 
    // 10 19:invokestatic #27 <Method String Integer.toString(int)> 
    // 11 22:astore_3 
    // 12 23:getstatic  #32 <Field PrintStream System.out> 
    // 13 26:new    #16 <Class StringBuilder> 
    // 14 29:dup 
    // 15 30:aload_2 
    // 16 31:invokestatic #38 <Method String String.valueOf(Object)> 
    // 17 34:invokespecial #44 <Method void StringBuilder(String)> 
    // 18 37:aload_3 
    // 19 38:invokevirtual #47 <Method StringBuilder StringBuilder.append(String)> 
    // 20 41:invokevirtual #23 <Method String StringBuilder.toString()> 
    // 21 44:invokevirtual #50 <Method void PrintStream.println(String)> 
    // 22 47:return 
    } 
+1

No estoy seguro de que te esté siguiendo. ¿Demostraste que "" +123 es mejor que Integer.toString (123)? – corgrath

+0

+1 para verificar realmente. Ahora, ¿qué pasa con los tipos de objetos en lugar de los tipos de vainas? –

+0

¿Qué son los tipos de vainas? – corgrath

6

Se expande a "" + String.valueOf (yourObject) y, por lo tanto, realiza una concatenación innecesaria. La concatenación implica asignar una cadena adicional y hacer una copia adicional del valor de la cadena.

+5

y la versión de tostring indica claramente la intención. "Convierta este valor en una cadena" –

+1

Esto no es estrictamente correcto desde el punto de vista de generación de código, por lo tanto, me abstendré de la votación ascendente. En realidad (para Java 6u20, con el que probé) se expande a: 'new StringBuilder(). Append (" "). Append (yourObject) .toString()', suponiendo que 'yourObject' no es constante. –

20

Es ineficaz, ya que implica una cadena de concatenación innecesaria, por lo tanto la creación de uno o dos objetos adicionales String, aunque creo que el JIT puede optimizarlo.

Para mí, el problema más grande es que el código es menos claro. Llamar a toString es una expresión estándar, comprensible para todos los desarrolladores de Java (con suerte :-), por lo que debería preferir esto.

+3

La transparencia del código es crucial para mí. – Bart

+3

La claridad del código siempre debe ir antes de las micro optimizaciones. – JesperE

0
String s = "" + 123; // bad 

El código anterior crea una cadena temporal, para combinar "" y 123

+2

No es tan simple. Ver la respuesta del apilador. Si en lugar de 123 tiene un valor no constante, entonces estaría en lo correcto. –

Cuestiones relacionadas