2010-03-24 11 views
38

Diciamo che ho due variabili char e in seguito voglio concatenarle in una stringa. Questo è come lo farei:Concatenare con una stringa vuota per fare una conversione di stringhe davvero così brutta?

char c1, c2; 
// ... 

String s = "" + c1 + c2; 

Ho visto persone che dicono che il "trucco" "" + è "brutto", ecc, e che si dovrebbe usare String.valueOf o Character.toString invece. Io preferisco questo costrutto perché:

  • Io preferisco usare caratteristica del linguaggio, invece di chiamata API, se possibile
    • In generale, non è la lingua di solito più stabile rispetto al API?
    • Se la funzione lingua nasconde solo la chiamata all'API, motivo ancora più forte per preferirlo!
      • Ancora più astratto! Nascondersi è buono!
  • mi piace che la c1 e c2 sono visivamente sullo stesso livello
    • String.valueOf(c1) + c2 suggerisce qualcosa è speciale c1
  • E 'più breve.

C'è davvero un buon argomento per cui String.valueOf o Character.toString è preferibile a "" +?


film: in java.lang.AssertionError, la seguente riga appare 7 volte, ognuna con un diverso tipo:

this("" + detailMessage); 
+0

Ovviamente 'String.valueOf (c1) + c2' sarebbe strano, se si va su quella strada si scrivere' String.valueOf (c1) + String.valueOf (c2) ' – NomeN

+4

@NomeN: si potrebbe scrivi 'new String (new char [] {c1, c2})' –

+2

ad Trivia: le librerie di base di Java SE non sono esattamente una fonte di buon stile di codifica, questo è ben noto ;-) –

risposta

25

Gli argomenti sono validi; questa è una delle aree più espressive del linguaggio Java e l'idioma "" + sembra ben radicato, come hai scoperto.

Vedere String concatenation nel JLS.Un'espressione come

"" + c1 + c2 

equivale a

new StringBuffer().append(new Character(c1).toString()) 
        .append(new Character(c2).toString()).toString() 

tranne che tutti gli oggetti intermedi non sono necessari (quindi l'efficienza non è un motivo). Le specifiche dicono che un'implementazione può usare lo StringBuffer oppure no. Poiché questa funzione è incorporata nel linguaggio, non vedo alcun motivo per utilizzare il modulo più dettagliato, specialmente in un linguaggio già dettagliato.

+7

In realtà, no. Il JLS lo spiega in questo modo, ma il compilatore lo implementa in modo diverso. Eclipse compilatore produce bytecode equivalente a nuovo StringBuilder(). Append (c1) .Append (c2) .toString() Il compilatore javac (1.5) produce bytecode equivalente a nuovo StringBuilder(). Accodare ("") .append (c1) .append (c2) .toString() –

2

Credo che nel "" + var il + è effettivamente sovraccarico di effettuare la conversione:

Il linguaggio Java fornisce supporto speciale per l'operatore di concatenazione di stringhe (+) e per la conversione di altri oggetti in stringhe. La concatenazione delle stringhe viene implementata tramite la classe StringBuilder (o StringBuffer) e il relativo metodo append. Le conversioni di stringhe vengono implementate tramite il metodo toString, definito da Object ed ereditato da tutte le classi in Java. Per ulteriori informazioni sulla concatenazione e conversione delle stringhe

Quindi nessuna differenza e nessun problema da un punto di vista tecnico.

Formare un punto di vista di leggibilità: è una questione di preferenza personale o di stile di codifica concordato all'interno del team.

+0

Ho appena aggiunto il tag [coding-style] al domanda; questo è per lo più questo. – polygenelubricants

18

Il problema con questo costrutto è che di solito non esprime l'intento.

Rappresenta la concatenazione di una stringa con un altro valore, ma la concatenazione non è solitamente l'obiettivo di questa riga.

Nel caso specifico che hai dimostrato, la concatenazione è in realtà l'obiettivo, quindi questo codice fa esprimere l'intento.

Nell'uso più comune di questo approccio (String s = "" + intValue;), la concatenazione è semplicemente un effetto collaterale tollerato, mentre la conversione di intValue è l'obiettivo effettivo. E un semplice String.valueOf(intValue) esprime questa intenzione molto più chiara.

+8

Io non la penso così. '" "+ x' è estremamente comune, l'intento dovrebbe essere chiaro. – mafu

+0

+1 per una buona argomentazione; ancora non sono d'accordo, però. – polygenelubricants

+8

@mafutrct: se l'intento è chiaro solo quando hai visto quel costrutto esatto molte volte prima, allora non è chiaro come tale. Dimostra solo che il riconoscimento dei pattern funziona. –

2

A mio parere, "" + x è molto leggibile, breve e preciso al punto. Preferisco i costrutti più lunghi come String.valueOf. Il comportamento è ben definito ed è così comunemente in uso che trovo difficile definirlo un hack.

L'unica cosa che mi preoccupa un po 'sono le prestazioni - e sono molto positivo che non contenga di solito (anche se non ho misurato o guardato il binario). C'è anche una buona probabilità che questo tipo di concat sia ottimizzato, poiché dovrebbe essere facile da rilevare (questa è solo un'ipotesi).

+0

è importante se il tuo codice viene eseguito centinaia di migliaia di volte in un ciclo. – Epaga

+0

Nessuno lo userebbe in loop ad anello, si sta sempre usando il codice performante più conosciuto. Nel 99% dei casi, non è un problema. La leggibilità nel caso generale è molto più importante, imo. – mafu

1

A meno che l'app non abbia bisogno di ogni grammo di prestazioni, scrivere il codice più veloce da scrivere e più facile da leggere. "" + è una sintassi più lenta per l'esecuzione, ma sicuramente sembra più facile da leggere ogni volta che l'ho usata.

2

Che dire

new String(new char[] {a, b}) 

e se alot si potrebbe creare una classe "Strings" con:

public static String valueOf(char... chars) { 
    return new String(chars); 
} 

La linea sarebbe poi leggere

String s = Strings.valueOf(a, b); 

Nizza e corto.

cura

Un nome migliore potrebbe essere:

String s = Chars.asString(a, b); 
+0

Dovrebbe anche essere molto veloce, in quanto l'unica cosa che deve essere fatta è una copia dell'array che è abbastanza veloce. – whiskeysierra

+0

questa è una buona alternativa. – Epaga

+0

-1 nessuno può dire cosa fa questo senza guardare il metodo chiamato. Si prega di refactoring! –

4

Io preferisco usare String.valueOf per singoli conversioni - ma nel tuo caso si vuole veramente concatenazione.

Tuttavia, vorrei suggerire che questa versione sarebbe rimuovere tutti potenziale ambiguità:

String s = c1 + "" + c2; 

In questo modo non c'è possibilità, per quanto remota, di qualcuno considerare se C1 e C2 saranno aggiunti insieme prima la concatenazione.

0

Il modo migliore per conoscere è quello di compilare/decompilare il codice, ho usato Jad http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler) per questo, vedrete che la vostra espressione è stata trasformata in

String s = (new StringBuilder()). Accodare ("") .Append (CI) .Append (c2) .toString();

Come si può vedere javac fatto incluse aggiungere ("") chiamata, ma il suo costo è trascurabile, notando viene aggiunto al buffer di StringBuilder interno, è possibile verificare la fonte di StringBuilder

1

Lo stile "" + var ha un problema molto grande nel la mia opinione. Utilizza solo il metodo toString di var. Quindi se cambi il tipo di var in qualcos'altro, non otterrai un'eccezione. Un bell'esempio che ho appena riscontrato è che il tipo è stato modificato da int a Optional<Integer>. Il codice si compila ancora bene, ma ottieni un risultato completamente diverso.

Problemi correlati