Почему присвоение нулевого значения из трехмерного выражения для булевой переменной вызывает NPE?

У меня есть часть кода вроде этого:

public static void main(String[] args) throws Exception { String trueValue = Boolean.TRUE.toString(); String fieldValue = null; Boolean defaultValue = null; Boolean value = (fieldValue != null ? trueValue.equalsIgnoreCase(fieldValue) : defaultValue); System.out.println(value);
}

Когда defaultValue не равно null, код работает нормально, но когда defaultValue есть null, JVM выбрасывает a NullPointerException. Этот код был скомпилирован с использованием jdk 1.6.45.

Почему я получил это исключение?

3 ответа

Спецификация языка Java говорит:

Если один из второго и третьего операндов имеет примитивный тип <code>T</code>, а тип другого - результат применения преобразования бокса (п. 5.1.1) до <code>T</code>, то тип условного выражения <code>T</code>.


Это тернарный оператор. Поскольку первый вариант trueValue.equalsIgnoreCase(fieldValue) является логическим, предполагается, что второй вариант defaultValue является логическим, а не нулевым значением Boolean. Это странно, но похоже, что это происходит. Если вы выбрали первый вариант Boolean, ошибка исчезнет:

Boolean value = (fieldValue != null ? (Boolean) trueValue.equalsIgnoreCase(fieldValue) : defaultValue);


Из JLS: 15.25. Условный оператор?:

Если один из второго и третьего операндов имеет примитивный тип <code>T</code>, а тип другого - результат применения преобразования бокса (п. 5.1.1) до <code>T</code>, то тип условного выражения <code>T</code>.

Aka: когда 2-й и 3-й операнды являются примитивными и бокс-ссылочными типами, результат считается примитивным типом. В конце вашей операции вы снова боксируете его, но к тому времени вы уже пытались присвоить null примитивному типу - это невозможно.

Подпись String#equalsIgnoreCase равна...

public boolean equalsIgnoreCase

licensed under cc by-sa 3.0 with attribution.