Auto-unboxing necessita di ternary if-else


23

Questo pezzo di codice funziona bene: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

Ma questo genera un'eccezione puntatore null, mentre Eclipse avverte che è necessario un auto-unboxing: -

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Perché è così, qualcuno può guidare per favore?

Risposte:


22

Il tipo dell'espressione condizionale ternaria

1 <= 3 ? nullInt : -1

è int(il JLS contiene diverse tabelle che descrivono il tipo di operatore condizionale ternario in base ai tipi del 2o e 3o operando).

Pertanto, quando tenta di decomprimere nullIntin an int, NullPointerExceptionviene lanciato a.

Per ottenere il comportamento del tuo snippet if-else, devi scrivere:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Ora il tipo di espressione sarà Integer, quindi non si verificherà alcun unboxing.


4
Solo per aggiungere alla tua risposta, ecco le tabelle menzionate: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

Sono abbastanza sicuro che gli argomenti per l'operatore ternario debbano essere dello stesso tipo. Dal momento che si utilizza -1 e alcuni nullintcompilatori costanti tenta di deselezionare nullintper ottenere valore. E quindi autobox per archiviarlo in secondNullvariabile.


3

Questo perché quando i due operandi per l'operatore condizionale ? :sono un tipo primitivo e il suo tipo di riferimento inscatolato, viene eseguita una conversione unboxing ( JLS § 15.25.2 ):

Il tipo di un'espressione condizionale numerica è determinato come segue:

  • ...
  • Se uno dei secondi e terzi operandi è di tipo T primitivo e il tipo dell'altro è il risultato dell'applicazione della conversione di boxe (§5.1.7) a T, allora il tipo dell'espressione condizionale è T.

In generale, la sostituzione di ifun'istruzione con ? :un'espressione non mantiene sempre il significato del codice, poiché l' ? :espressione stessa deve avere un tipo di tempo di compilazione. Ciò significa che quando i tipi dei due operandi sono diversi, è necessario eseguire una conversione in uno o entrambi in modo che il risultato abbia un tipo di tempo di compilazione coerente.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.