2010-09-02 7 views
7

Secondo lo strumento PMD, il seguente è una cattiva pratica:Aggiungi una stringa vuota vs toString: perché è male?

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


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

Perché è una brutta cosa da fare?

+0

Apparentemente, per le costanti (statico/finale) "" + 123 è più efficiente. Per altri valori, usare toString è più efficiente. – corgrath

+0

"Statico/finale" può essere fuorviante. Un campo deve essere _tutto statico e finale per essere considerato una costante, e solo per le primitive e le stringhe. (Le variabili locali non sono mai considerate costanti.) –

+0

possibile duplicato di [È la conversione a String using ("" + ) cattiva pratica?] (Http://stackoverflow.com/questions/1572708/is-conversion-to-string- using-int-value-bad-practice) – McDowell

risposta

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

sarà compilato a:

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

così: "" 123 è ovvio un po 'meglio! Controllato 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:

per valori non-costanti:

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

Non sono sicuro di seguirti. Hai dimostrato che "" +123 è meglio di Integer.toString (123)? – corgrath

+0

+1 per il controllo effettivo. Ora per quanto riguarda i tipi di oggetto piuttosto che i tipi di pod? –

+0

Che cosa sono i tipi di pod? – corgrath

6

Si espande in "" + String.valueOf (yourObject) e pertanto esegue una concatenazione non necessaria. La concatenazione comporta l'allocazione di una stringa aggiuntiva e l'esecuzione di una copia aggiuntiva del valore della stringa.

+5

e la versione tostring afferma chiaramente l'intenzione. "Converti questo valore in una stringa" –

+1

Questo non è strettamente corretto dal punto di vista della generazione del codice, quindi mi asterrò dal upvoting. In realtà (per Java 6u20, che ho testato con) si espande in: 'new StringBuilder(). Append (" "). Append (yourObject) .toString()', assumendo che 'yourObject' non sia costante. –

20

È inefficiente, poiché implica una concatenazione di stringhe non necessarie, quindi la creazione di uno o due oggetti aggiuntivi String, anche se credo che il JIT possa ottimizzarlo.

Per me il problema più grande è che il codice è meno chiaro. Chiamare il numero toString è un idioma standard, comprensibile a tutti gli sviluppatori Java (si spera :-), quindi dovresti preferirlo.

+3

La trasparenza del codice è una cosa fondamentale per me. – Bart

+3

La chiarezza del codice dovrebbe sempre andare prima delle micro ottimizzazioni. – JesperE

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

Il codice di cui sopra crea una stringa temporanea, di coniugare "" e 123

+2

Non così semplice. Vedi la risposta dello stacker. Se invece di 123 hai un valore non costante, allora saresti corretto. –