почему спецификация написана таким образом?
Я не могу ответить почему , потому что я не написал спецификацию.Но я могу предложить причину, по которой не должно быть иначе.
Когда второй и третий параметры имеют разные типы, и оба типа могут быть преобразованы в числовые типы, они подвергаются двоичное числовое продвижение .Это то же самое, что и для других операторов, принимающих числовые операнды, например, +
.
. Вы можете получить тот же NPE, если попытаетесь добавить int
и Integer null
:
System.out.println(1 + (Integer) null);
В этом случае вы не можете сделать что-нибудь полезное, поместив от 1 до Integer.valueOf(1)
.
Было бы непоследовательным, если бы числовые типы обрабатывались по-разному между операторами +
и ?:
(*).И условный оператор должен использовать некоторую форму двоичного числового преобразования, чтобы иметь возможность обрабатывать примитивные операнды различных типов, например, int
и double
.
Взгляд наспецификация для условного оператора должна убедить вас, что его обработка типов уже безумно сложна (см. таблицы с 15.25-A по E), и поэтому делать это не следует.
К сожалению, вы можете так выстрелить себе в ногу;но это только то, каков язык.
Я считаю, что проблема здесь заключается в автобоксе как общей языковой функции;без этого не было бы такой проблемы, потому что вы должны были бы распаковать сами.
(*) На самом деле, это ведет себя немного по-другому.Например, (Integer) null + (Integer) null
будет автоматически распакован, тогда как condition ? (Integer) null : (Integer) null
будет не автоматически распакован.Эта разница возникает из-за того, что условный оператор указывает, что перед применением двоичного числового преобразования выполняется проверка для тех же типов операндов.