2013-06-26 13 views
5

Come mai?StringBuilder aggiunge null come "null"

StringBuilder sb = new StringBuilder(); 

    sb.append("Hello"); 
    sb.append((String)null); 
    sb.append(" World!"); 
    Log.d("Test", sb.toString()); 

Produce

06-25 18: 24: 24,354: D/Test (20740): Hellonull mondo!

mi aspetto che aggiungendo una stringa null sarà Non aggiungere a tutti !!
BTW, il cast a String è necessario perché StringBuilder.append() ha molte versioni sovraccaricate.

ho semplificato il mio codice per fare un punto qui, nel mio codice un ottenuto un metodo che restituisce una stringa

public String getString() { ... } 
... 
sb.append(getString()); 
... 

getString() a volte restituisce null; ora devo testarlo se voglio usare un StringBuilder !!!!

Inoltre, chiariamo la mia domanda qui: come posso ottenere StringBuilder.append() per accettare, in modo elegante, una stringa nulla e non convertirlo nella stringa letterale "null".
Con elegante intendo che non voglio ottenere la stringa, testare se è null e solo dopo aggiungerla. Sto cercando un elegante oneliner.

+0

possibile duplicato di [StringBuilder append() e valori nulli] (http://stackoverflow.com/questions/3960712/stringbuilder-append-and-null-values) –

risposta

4

Questo è solo il modo in cui è. null viene aggiunto come "null". Allo stesso modo, quando si stampa null con System.out.println(null) si stampa "null".

Il modo per evitare cioè che il metodo che restituisce stringa getString() controlli per null:

public String getString() { 
    ... 
    if (result == null) { 
     return ""; 
    } 
} 
5
How come? 

sua clearly written in docs

I caratteri dell'argomento stringa sono allegate, in ordine, aumentando la lunghezza di questa sequenza per la lunghezza dell'argomento. Se str è null, vengono aggiunti i quattro caratteri "null".

Quindi si prega di inserire un controllo Null prima di aggiungere.

+1

Ok, è scritto nella documentazione. Ma, è solo che ne sono molto controintuitivo? Ho imparato che una stringa nulla è una stringa che non esiste. E senza aprire una discussione, non capisco perché l'abbiano fatto in quel modo. In questo momento sto sbattendo la testa sulla scrivania. – ilomambo

+1

Penso che tu stia confondendo una stringa vuota e vuota. Come dici tu (String) null è una stringa che non esiste, che è rappresentata da "null" nel dominio String.D'altra parte la stringa vuota "" non ha sorprendentemente la rappresentazione "". Quando esegui il debug o stampi alcune variabili String, vuoi effettivamente vedere che sta puntando a null, quindi ha senso. – LastFreeNickname

+0

@LastFreeNickname Non proprio, quando una stringa è 'null' non voglio/non vedo nulla. Se uso un debugger voglio ispezionare la variabile e vedere il suo valore come 'null'. Sembra non tanto tempo fa che in un corso di algebra il professore ha detto che esiste un simbolo speciale per indicare un insieme vuoto, un insieme senza elementi, che è l'analogo di una stringa nulla. Mostrare qualcosa per una stringa nulla sta rompendo la coerenza con la stessa definizione di 'null'. Ma questo sta piangendo sul latte versato, un giorno spero di imparare il motivo per cui. – ilomambo

0

Che dire di scrittura di un metodo di utilità come

public static void appendString(StringBuilder sb, String st) { 
    sb.append(st == null ? "" : st); 
} 

o questo l'operatore ternario è molto utile.

0
String nullString = null; 
StringBuilder sb = new StringBuilder(); 
sb.append("Hello"); 
if (nullString != null) sb.append(nullString); 
sb.append(" World!"); 
Log.d("Test", sb.toString()); 

C'è! L'ho fatto in una riga :)

+1

:-) nessuna domanda è molto elegante :-) – ilomambo

2

Si comporta in questo modo, perché null non è un String vuoto come ci si pensa. Vuoto String sarebbe new String("");. Fondamentalmente il metodo append() aggiunge "null" se assume il valore null come parametro.

+0

Non ho detto "stringa vuota" ho detto "una stringa che non esiste" – ilomambo

0

Una linea?

sb.append((getString()!=null)?getString():""); 

terminato. Ma è inutile come hanno fatto chiamare getString() controllo costruzione due volte

come è stato suggerito in getString() metodo

1

AbstractStringBuilder classe aggiunge un oggetto attraverso String.valueOf(obj) metodo che a sua volta converte NULL nella stringa letterale "null". Pertanto non vi è alcun metodo integrato per aiutarti qui. È necessario utilizzare l'operatore ternario all'interno del metodo append o scrivere un metodo di utilità per gestirlo, come suggerito da altri.

2

EDIT
mio previous answer non rifletteva il motivo appropriato per tale comportamento di StringBuilder come richiesto dalle OP. Grazie a @Stephen C per aver ricordato che

mi aspetto che aggiungendo una stringa null non aggiungerà a tutti !!

Ma si sta aggiungendo. Il motivo di tale comportamento di StringBuilder è nascosta in dettaglio attuazione append(Object obj) metodo che ci porta a AbstractStringBuilder#append(String str) metodo che è definita come segue:

public AbstractStringBuilder append(String str) { 
    if (str == null) str = "null"; -->(1) 
    //....... 
    return this; 
} 

Si precisando chiaramente che se l'ingresso String è nullo, allora è cambiato in stringa letterale "null" e quindi si elabora ulteriormente.

Come posso ottenere StringBuilder.append() per accettare, in modo elegante, una stringa nulla e non convertirlo nella stringa letterale "null".

è necessario controllare la data String per null esplicitamente e poi procedere. Per esempio:

String s = getString(); 
StringBuffer buf = new StringBuffer(); 
//Suppose you want "Hello "<value of s>" world" 
buf.append("Hello "); 
buf.append(s==null?" world" : s+" world"); 
+0

In senso stretto, il JLS non è definitivo per questo. Il JLS sta in realtà specificando la semantica dell'operatore "+". Si potrebbe sostenere che è una comoda coincidenza che 'StringBuilder.append (null)' implementa il comportamento richiesto. (Sono sicuro che non è una coincidenza, ma hai capito il mio punto ...) –

+0

@StephenC: Sì hai ragione ... Il mio errore .. –

1

Questo funziona per voi

public static String getString(StringBuilder sb, String str) { 
    return sb.append(str == null ? "" : str).toString(); 
} 
0

È possibile anche scrivere decoratore per StringBuilder, che può controllare quello che vuoi:

class NotNullStringBuilderDecorator { 

    private StringBuilder builder; 

    public NotNullStringBuilderDecorator() { 
     this.builder = new StringBuilder(); 
    } 

    public NotNullStringBuilderDecorator append(CharSequence charSequence) { 
     if (charSequence != null) { 
      builder.append(charSequence); 
     } 

     return this; 
    } 

    public NotNullStringBuilderDecorator append(char c) { 
     builder.append(c); 

     return this; 
    } 

    //Other methods if you want 

    @Override 
    public String toString() { 
     return builder.toString(); 
    } 
} 

Esempio di utilizzo:

NotNullStringBuilderDecorator sb = new NotNullStringBuilderDecorator(); 
sb.append("Hello"); 
sb.append((String) null); 
sb.append(" World!"); 

System.out.println(sb.toString()); 

W con questa soluzione non devi modificare le classi POJO.

Problemi correlati