Автоматичне розпакування потребує потрійного, якщо ще


23

Цей фрагмент коду працює чудово: -

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

Але це викидає виключення з нульовим покажчиком, тоді як Eclipse попереджає про необхідність автоматичного розпакування: -

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

Чому це так, може хтось вподобає?

Відповіді:


22

Тип потрійного умовного виразу

1 <= 3 ? nullInt : -1

є int(JLS містить кілька таблиць, які описують тип потрійного умовного оператора залежно від типів 2-го та 3-го операндів).

Тому, коли він намагається відключити папку nullIntдо int, NullPointerExceptionвикидається a .

Для того, щоб отримати поведінку свого фрагмента if-else, вам потрібно написати:

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

Тепер тип виразу буде Integer, тому розпакування не відбудеться.


4
Просто для додання вашої відповіді, ось згадані таблиці: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

Я майже впевнений, що аргументи до потрійного оператора повинні бути такого ж типу. Оскільки ви використовуєте -1 і якийсь постійний nullintкомпілятор намагається розблокувати, nullintщоб отримати значення. А потім автобокс для зберігання в secondNullзмінній.


3

Це пояснюється тим, що коли два операнди для умовного оператора ? :є примітивним типом, а його посилання в коробці - типовим перетворенням ( JLS §15.25.2 ):

Тип числового умовного виразу визначається так:

  • ...
  • Якщо один з другого та третього операндів має примітивний тип T, а тип другого є результатом застосування перетворення боксу (§5.1.7) до T, то тип умовного виразу - Т.

Взагалі, заміна ifоператора ? :виразом не завжди зберігає значення коду, оскільки сам ? :вираз повинен мати тип часу компіляції. Це означає, що типи двох операндів різні, перетворення повинно бути виконане в один або обидва, щоб результат мав послідовний тип часу компіляції.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.