Automatyczne rozpakowywanie wymaga potrójnego if-else


23

Ten fragment kodu działa dobrze: -

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

Zgłasza to jednak wyjątek o wartości zerowej, podczas gdy środowisko Eclipse ostrzega o potrzebie automatycznego rozpakowywania:

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

Dlaczego tak jest, czy ktoś może poprowadzić?

Odpowiedzi:


22

Typ trójskładnikowego wyrażenia warunkowego

1 <= 3 ? nullInt : -1

jest int(JLS zawiera kilka tabel opisujących typ trójskładnikowego operatora warunkowego w zależności od typów drugiego i trzeciego argumentu).

Dlatego, gdy próbuje rozpakować nullIntdo an int, generowany NullPointerExceptionjest a .

Aby uzyskać zachowanie fragmentu kodu if-else, musisz napisać:

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

Teraz typem wyrażenia będzie Integer, więc nie nastąpi rozpakowanie.


4
Aby dodać do swojej odpowiedzi, oto wymienione tabele: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

Jestem prawie pewien, że argumenty dla operatora trójskładnikowego muszą być tego samego typu. Ponieważ używasz -1 i jakiś stały nullintkompilator próbuje rozpakować, nullintaby uzyskać wartość. A następnie autobox to do przechowywania w secondNullzmiennej.


3

Wynika to z faktu, że gdy dwa operandy operatora warunkowego ? :są typem pierwotnym i typem referencji w pudełku, następuje konwersja rozpakowywania ( JLS § 15.25.2 ):

Typ liczbowego wyrażenia warunkowego określa się w następujący sposób:

  • ...
  • Jeśli jeden z drugiego i trzeciego operandu jest typu pierwotnego T, a drugi typ jest wynikiem zastosowania konwersji boksu (§ 5.1.7) na T, wówczas typem wyrażenia warunkowego jest T.

W ogóle, zastępując ifoświadczenie o ? :wyrażeniu nie zawsze zachować rozumieniu kodeksu, ponieważ ? :samo wyrażenie musi mieć typ kompilacji. Oznacza to, że gdy typy dwóch operandów są różne, należy wykonać konwersję na jeden lub oba, aby wynik miał spójny typ czasu kompilacji.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.