4

我正在玩弄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

有人对此有很好的解释吗?

4

2 回答 2

3

三元组必须为两个条件返回相同的类型,因此您的第一个结果 ( Integer)被提升为double 以匹配2.0。也可以看看,

Object object1 = boo ? new Integer(1) : new Double(2.0);
System.out.println(object1.getClass().getName());

这记录在JLS-15.25.2 - Numeric Conditional Expressions中,内容为(部分)

否则,二进制数值提升 ( §5.6.2 ) 将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

请注意,二进制数字提升执行值集转换(§5.1.13)并且可能执行拆箱转换(§5.1.8)。

于 2016-01-09T13:50:35.040 回答
1

JLS第 15.25 节有一个表格,根据其操作数的类型总结了条件表达式的类型。对于 and 的情况IntegerDouble该表表明该类型将是对参数应用二进制数字提升的结果(第 15.25.2 节

否则,二进制数值提升(第 5.6.2 节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

请注意,二进制数字提升执行值集转换(第 5.1.13 节)并可能执行拆箱转换(第 5.1.8 节)。

引用二进制数字提升

如果任何操作数属于引用类型,则将对其进行拆箱转换(第 5.1.8 节)。
...
如果任一操作数是双精度类型,则另一个将转换为双精度。


这就是正在发生的事情

Object object1 = boo ? new Integer(1) : new Double(2.0);
  • 引用类型new Integer(1)被取消装箱到原语int1。
  • 引用类型new Double(2.0)未装箱到原始double2.0。
  • 执行二进制数字提升,结果为 类型double。在这种情况下,因为boois true,原语int1 将被提升为double1.0。
  • 由于您将结果存储在 中Object,因此原始结果被装箱到其包装器类型中。

对于的情况

Object object2;
if (boo)
    object2 = new Integer(1);
else
    object2 = new Double(2.0);

if/else 构造不执行数字提升。实际上不会有任何拳击转换。既然bootrue,该if部分将被执行并object2具有价值new Integer(1)

于 2016-01-09T13:49:54.993 回答