Ответ 1
Разница заключается в статической типизации выражений во время компиляции:
Резюме
E1: `(false ? 1.0f : null)`
- arg 2 '1.0f' : type float,
- arg 3 'null' : type null
- therefore operator ?: : type Float (see explanation below)
- therefore autobox arg2
- therefore autobox arg3
E2: `(false ? 1.0f : (false ? 1.0f : null))`
- arg 2 '1.0f' : type float
- arg 3 '(false ? 1.0f : null)' : type Float (this expr is same as E1)
- therefore, outer operator ?: : type float (see explanation below)
- therefore un-autobox arg3
Подробное объяснение:
Здесь я понимаю, что прочитал спецификацию и отработал назад от полученного результата. Оно сводится к типу третьего операнда внутреннего условия f2 - это нулевой тип, тогда как тип третьего операнда внешнего условия f2 считается Float.
Примечание. Важно помнить, что определение типа и вставка кода бокса/распаковки выполняется во время компиляции. Фактическое выполнение кода бокса/распаковки выполняется во время выполнения.
Float f1 = (false ? 1.0f : null);
Float f2 = (false ? 1.0f : (false ? 1.0f : null));
Условие f1 и внутреннее условие f2: (false? 1.0f: null)
Условие f1 и внутреннее условие f2 идентичны: (false? 1.0f: null). Типы операндов в условном условии f1 и внутреннем условии f2:
type of second operand = float
type of third operand = null type (§4.1)
Большинство правил в §15.25 переданы и эта окончательная оценка действительно применяется:
В противном случае второй и третий операнды имеют типы S1 и S2 соответственно. Пусть T1 является типом, который возникает в результате применения преобразования бокса в S1, и пусть T2 является типом, который возникает в результате применения преобразования бокса в S2. Тип условного выражения является результатом применения преобразования захвата (§5.1.10) в lub (T1, T2) (§15.12.2.7).
S1 = float
S2 = null type
T1 = Float
T2 = null type
type of the f1 and f2 inner conditional expressions = Float
Так как для f1, присвоение опорного Поплавка переменных, результат выражения (нуль) успешно назначен.
Для f2 external conditional: (false? 1.0f: [f2 internal conditional])
Для внешнего условия f2 типы:
type of second operand = float
type of third operand = Float
Обратите внимание на разницу в типах операндов по сравнению с внутренними условиями f1/f2, которые напрямую ссылаются на нулевой литерал (§4.1). Из-за этой разницы, связанной с наличием двух типов числовых конвертируемых, это правило из §15.12.2.7 применяется:
В противном случае, если второй и третий операнды имеют типы, которые конвертируются (§5.1.8) в числовые типы, тогда существует несколько случаев:...
- В противном случае для типов операндов применяется двоичное числовое продвижение (§5.6.2), а тип условного выражения - продвинутого типа второго и третьего операндов. Обратите внимание, что бинарное числовое продвижение выполняет распаковывание преобразования (§5.1.8) и преобразование значений (§5.1.13).
Из-за преобразования unboxing, выполняемого с результатом внутреннего условия f2 (null), возникает исключение NullPointerException.