Нечетное Java троичное поведение при назначении значения. Что Java делает за сценой, чтобы это произошло? - PullRequest
10 голосов
/ 18 февраля 2020

Несколько дней спустя go я столкнулся с увлекательным сценарием, в котором я не смог найти никакой документации о том, как и почему Java допускает следующее. (Этот фрагмент является просто упрощенной формой ошибки.)

    @Test
    public void test() {
      boolean bool = false;
      Integer intVal = Integer.valueOf(5);
      Long longVal = null;
      Long result = bool ? intVal : longVal;

      System.out.println(" > " + result);
   }

во фрагменте выше:

если bool = true, тогда вы получите значение '5';

но если bool = false, то при попытке оценить троичную операцию вы получите исключение нулевого указателя. НЕ оператор print.


Чтобы исправить это, я просто изменяю 'result' на

Long result = bool ? Long.valueOf(intVal) : longVal;

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

если bool = true, тогда вы получите значение '5';

, но если bool = false, тогда вы получите 'null'


, теперь самое интересное то, что если вы разделите это на обычный оператор if / else, тогда java НЕ позволяет вам скомпилировать

longVal = intVal; 

, но не перехватывает это через троичный оператор. Так что же делает Java, чтобы сделать его нулевым в исходном фрагменте?

(java 11)

1 Ответ

10 голосов
/ 18 февраля 2020

Когда вы делаете это:

Long result = bool ? intVal : longVal

Это выражение возвращает long и, когда bool ложно, оно пытается распаковать null в значение Long, чтобы соответствовать result переменная и выдает NPE.

Когда вы делаете это:

Long result = bool ? Long.valueOf(intVal) : longVal

Это выражение уже возвращает Long, тогда нет необходимости в распаковке, и значение null успешно назначено к переменной result.

Ссылка:

Как обсуждалось в разделе комментариев, чтобы лучше понять, почему это происходит, проверьте следующие разделы JLS:

...