2015-04-08 8 views
6

consideri sotto uno:Perché toString() su un'istanza Object (che è null) non sta lanciando NPE?

Object nothingToHold = null; 

System.out.println(nothingToHold); // Safely prints 'null' 

Qui, SYSOUT deve essere in attesa String. Quindi toString() deve essere richiamato su istanza.

Quindi perché null.toString() funziona in modo eccezionale? Sysout si sta prendendo cura di questo?

MODIFICA: In realtà ho visto questa cosa strana con l'append() di StringBuilder. Così provato con Sysout. Entrambi si comportano nello stesso modo. Quindi anche quel metodo sta facendo attenzione?

+1

perché 'null' non è un oggetto così non avere proprietà né metodi. 'println()' richiede 'Object', non' String' e controlla se è 'null' da solo. –

risposta

13

PrintWriter s' println(Object) (che è il metodo chiamato quando si scrive System.out.println(nothingToHold)) chiede String.valueOf(x) come spiegato nella Javadoc:

/** 
* Prints an Object and then terminates the line. This method calls 
* at first String.valueOf(x) to get the printed object's string value, 
* then behaves as 
* though it invokes <code>{@link #print(String)}</code> and then 
* <code>{@link #println()}</code>. 
* 
* @param x The <code>Object</code> to be printed. 
*/ 
public void println(Object x) 

String.valueOf(Object) converte il null per "nullo":

/** 
* Returns the string representation of the <code>Object</code> argument. 
* 
* @param obj an <code>Object</code>. 
* @return if the argument is <code>null</code>, then a string equal to 
*   <code>"null"</code>; otherwise, the value of 
*   <code>obj.toString()</code> is returned. 
* @see  java.lang.Object#toString() 
*/ 
public static String valueOf(Object obj) 
+2

Per essere chiaro 'object.toString()' garantirà un NPE se l'oggetto è nullo.Provalo tu stesso 'System.out.println()' funziona sul riferimento dell'oggetto per iniziare. PrintWriter sa quando viene passato un riferimento nullo, quindi passerà con garbo e stamperà 'null'. Ma se provate e chiamate 'toString()' da 'null', sicuramente genererà NPE. – ha9u63ar

8

Il metodo PrintStream#println(Object s) invoca il metodo PrintStream#print(String s), che controlla innanzitutto è il se l'argomento è null e se è, quindi imposta solo "null" da stampare come un normale String.

Tuttavia, ciò che è passato al metodo .print() è "null" come String, perché i rendimenti String.valueOf(String s)"null" prima che il metodo .print() essere invocati.

public void print(String s) { 
    if (s == null) { 
     s = "null"; 
    } 
    write(s); 
} 
+0

'println (Object)' verrebbe chiamato. Non è una variabile 'String', è un' Object' il compilatore non guarda all'interno del valore per decidere cosa chiamare. L'unica volta che questo è vero se è stato chiamato lista così: 'println (null)' – weston

+2

Quindi ora segue che questo chiama 'String.valueOf' ed è questo che introduce la stringa' 'null ''. – weston

+1

@weston - Ya. Hai ragione :) .. Avevo provato passando 'nullo' direttamente ai metodi personalizzati. Una volta assegnato il riferimento, verrà utilizzato il riferimento * effettivo * :) – TheLostMind

0

Ecco la documentazione per println()

Stampa una stringa seguita da una nuova riga. La stringa viene convertita in una matrice di byte utilizzando la codifica scelta durante la costruzione di in questo flusso. I byte vengono quindi scritti nello stream di destinazione con write (int).

Se si verifica un errore I/O, lo stato di errore di questo flusso è impostato su true.

NULL può convertire in byte.

0
Object nothingToHold = null; 
    System.out.println(nothingToHold != null ? nothingToHold : "null String or any thing else"); 

Ciò dell'uscita del display se il nothingToHold (Object) non è uguale a zero, altrimenti si stampa il messaggio come "String null o qualsiasi altra cosa"

Problemi correlati