На днях я столкнулся с действительно странным NullPointerException
, вызванным неожиданным типом в тернарном операторе. Учитывая эту (бесполезную примерную) функцию:
Integer getNumber() {
return null;
}
Я ожидал, что следующие два сегмента кода будут точно идентичными после компиляции:
Integer number;
if (condition) {
number = getNumber();
} else {
number = 0;
}
против.
Integer number = (condition) ? getNumber() : 0;
.
Выключается, если condition
- true
, условие if
работает отлично, а троичный отступ во втором сегменте кода вызывает NullPointerException
. Кажется, что тройная операция решила набрать оба варианта до int
, прежде чем автоматически поместить результат в Integer
!?! Фактически, если я явно применяю 0
к Integer
, исключение исчезает. Другими словами:
Integer number = (condition) ? getNumber() : 0;
- это не то же самое, что:
Integer number = (condition) ? getNumber() : (Integer) 0;
.
Итак, кажется, что существует байт-кодовое различие между тернарным оператором и эквивалентным if-else
-statement (чего я не ожидал). Что вызывает три вопроса: почему существует разница? Является ли это ошибкой в тройной реализации или есть причина для типа cast? Учитывая, что существует разница, тройная операция более или менее эффективна, чем эквивалентное if
-стояние (я знаю, разница не может быть огромной, но все же)?