Продвижение числового типа с условным выражением
Я играл с Java и кое-что заметил. Это может быть лучше всего показано здесь:
boolean boo = true;
Object object1 = boo ? new Integer(1) : new Double(2.0);
Object object2;
if (boo)
object2 = new Integer(1);
else
object2 = new Double(2.0);
System.out.println(object1);
System.out.println(object2);
Я ожидаю, что они будут одинаковыми, но вот что напечатано:
1.0
1
У кого-нибудь есть хорошее объяснение этому?
3 ответа
Тройка должна возвращать один и тот же тип для обоих условий, поэтому ваш первый результат (Integer
) повышается до двойного соответствия 2.0
, Смотрите также,
Object object1 = boo ? new Integer(1) : new Double(2.0);
System.out.println(object1.getClass().getName());
Это задокументировано в JLS-15.25.2 - Числовые условные выражения, которые читаются (частично)
В противном случае двоичное числовое продвижение ( §5.6.2) применяется к типам операндов, а тип условного выражения является продвинутым типом второго и третьего операндов.
Обратите внимание, что двоичное числовое продвижение выполняет преобразование набора значений ( §5.1.13) и может выполнять преобразование без коробки ( §5.1.8).
В разделе 15.25 JLS есть таблица, в которой обобщается тип условного выражения на основе типа его операндов. Для случая Integer
а также Double
таблица говорит, что тип будет результатом применения двоичного числового продвижения к аргументам ( §15.25.2)
В противном случае двоичное числовое продвижение (§5.6.2) применяется к типам операндов, а тип условного выражения является продвинутым типом второго и третьего операндов.
Обратите внимание, что двоичное числовое продвижение выполняет преобразование набора значений (§5.1.13) и может выполнять преобразование без коробки (§5.1.8).
Цитирование двоичного числового продвижения:
Если какой-либо операнд имеет ссылочный тип, он подвергается распаковке преобразования (§5.1.8).
...
Если один из операндов имеет тип double, другой преобразуется в double.
Это то, что происходит для
Object object1 = boo ? new Integer(1) : new Double(2.0);
- Тип ссылки
new Integer(1)
распакован в примитивint
1. - Тип ссылки
new Double(2.0)
распакован в примитивdouble
2,0. - Двоичное числовое продвижение выполняется, и результат имеет тип
double
, В этом случае, так какboo
являетсяtrue
Примитивint
1 будет повышен доdouble
как 1.0. - Поскольку вы сохраняете результат в
Object
, примитивный результат упакован в его тип оболочки.
Для случая
Object object2;
if (boo)
object2 = new Integer(1);
else
object2 = new Double(2.0);
конструкция if / else не выполняет числовое продвижение. На самом деле не будет никакого преобразования бокса. поскольку boo
является true
, if
часть будет выполнена и object2
будет иметь значение new Integer(1)
,
Когда троичный оператор условия имеет целочисленные значения и двойные в качестве 2-го и 3-го операндов, его тип - это тип, который вы получаете после применения двоичного числового продвижения. Двоичное числовое продвижение в этом случае включает в себя распаковку операндов в int
а также double
а затем расширение примитивного преобразования преобразует int
в double
, Следовательно, тип выражения является двойным, и оно упаковано в Double
для того, чтобы быть назначенным на Object
ссылка.