2011-12-15 12 views
9

Perché la seguente riga di codice produce un NullPointerException?NullPointerException nell'espressione ternaria con null Long

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

Capisco che unboxing in corso sull'automezzo null, ma perché?

Nota che

Long v = (Long) null; 

non produce l'eccezione.

+0

Si esegue a v = ((1 == 2)? Long.MAX_VALUE: (Long) null); questo è sempre falso, quindi provi sempre a trasmettere null a Long. Questo sembra non essere permesso e getta la tua eccezione. – evildead

+0

Perché dovresti avere una tale linea di codice? La curiosità intellettuale o è un frammento del codice di produzione attuale? – Paul

+1

@Paul e evildead, sembra un codice di esempio per dimostrare l'ordine di unboxing. – Steven

risposta

9

in modo che appaia evidente che hai solo di box se la condizione è vera, e non ci dovrebbero essere boxe, se la condizione è falsa. Tuttavia, l'espressione dell'operatore ternario deve avere un particolare tipo statico. Quindi abbiamo Long e long. Il JLS afferma che il risultato sarà il primitivo (altrettanto bene - immagina se l'operatore fosse, per esempio, + o anche ==). Quindi l'operatore ternario forzerà l'unboxing, e solo allora l'assegnazione causerà un pugilato.

Se si dovesse sostituire il codice con l'equivalente if-else, allora si sarebbe semplicemente avere un incarico da long a Long e da Long a Long, che non avrebbe alcun unboxing e così funzionare bene.

IIRC, questo è coperto è Bloch & Java Puzzlers di Gafter.

0

Dal JSL

  1. Se il secondo e terzo operandi hanno lo stesso tipo (che può essere il tipo nullo), allora questo è il tipo dell'espressione condizionale.
  2. Se uno dei secondi e terzi operandi è di tipo boolean e il tipo dell'altro è di tipo Boolean, il tipo di espressione condizionale è boolean.

Nella seguente dichiarazione del tipo di secondo operando è long e terzo è Long.

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

Questo funzionerà se un'espressione è vera.

Long v= 1 == 1 ? Long.MAX_VALUE : (Long) null; 

Oppure puoi lanciarlo.

Long v= 1 == 2 ? Long.valueOf(Long.MAX_VALUE) : (Long) null; 
+0

Sì, so che sta facendo unboxing e che non è possibile annullare la cancellazione di null. Stavo chiedendo perché sta cercando di eseguire unboxing in questo caso. – jonderry

+0

Non è del tutto corretto. Sta provando a rimuovere un oggetto 'Long' nullo; il cast non è il problema. Puoi lanciare 'null' su qualsiasi tipo di oggetto, vedi la specifica del linguaggio Java [sezione 5.5] (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5), sotto "Se un cast per un tipo di riferimento non è un errore in fase di compilazione, ci sono diversi casi:" – Paul

Problemi correlati