Почему присвоение нулевого значения из трехмерного выражения для булевой переменной вызывает 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.

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

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

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

public boolean equalsIgnoreCase