Java: унарный, если - npe - PullRequest
       9

Java: унарный, если - npe

0 голосов
/ 18 октября 2011

Почему этот код может вызвать NPE? Findbugs подсказывают мне, что это может произойти, и иногда это происходит

Есть идеи?

public Integer whyAnNPE() {
    return 1 == 2 ? 1 : 1 == 2 ? 1 : null;
}

1 Ответ

4 голосов
/ 18 октября 2011

РЕДАКТИРОВАТЬ: Код в вопросе не было, когда я написал этот ответ.

Вот еще один способ сделать его немного более понятным:

public static Integer maybeCrash(boolean crash) {
    return true ? (crash ? null : 1) : 0;
}

Важным моментом является то, что мыздесь есть два условных выражения.Внутренний имеет тип Integer из-за последней маркированной точки в определении типа, как указано в разделе 15.25 .

В этот момент мы имеем ситуацию, подобнуюthis:

public static Integer maybeCrash(boolean crash) {
    Integer tmp = null;
    return true ? tmp : 0;
}

Теперь для условного выражения , остающегося , применяется предыдущий пункт маркера, и выполняется двоичное числовое продвижение .Это, в свою очередь, вызывает распаковку в качестве первого шага, который не выполняется.

Другими словами, условное выражение, подобное этому:

condition ? null-type : int

включает в себя возможность упаковки intна Integer, но такое условие:

condition ? Integer : int

включает в себя возможность распаковки Integer на int.


Оригинальный ответ

Вот довольно простой пример, который на самом деле является действительным Java:

public class Test {
    public static void main(String[] args) {
        int x = args.length == 0 ? 1 : null;
    }
}

Это эффективно:

int tmp;
if (args.length == 0) {
   tmp = 1;
} else {
   Integer boxed = null;
   tmp = boxed.intValue();
}

Очевидно, что шаг распаковки здесь будет безумным.В основном это происходит из-за неявного преобразования нулевого выражения в Integer и из Integer в int посредством распаковки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...