Продвижение числового типа с условным выражением

Я играл с 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 ссылка.

Другие вопросы по тегам