Java中带有盒装类型的三元条件的奇怪行为

2022-09-01 22:58:02

我的应用程序(简化版)中有这段代码:

Object result;
if (check)
    result = new Integer(1);
else
    result = new Double(1.0);
System.out.println(result);
return result;

然后我决定将 if-else 语句重构为三元条件表达式,以便我的代码更加简洁:

Object result = check ? new Integer(1) : new Double(1.0);
System.out.println(result);
return result;

事实证明,如果检查是两个版本打印不同的结果:true

1

艺术

1.0

三元条件不等同于相应的 if-else 吗?


答案 1

if/else 和条件(三元)表达式并不完全等价。条件表达式的结果必须具有类型。

您正在观察数字类型提升(或类型强制)的影响。

以下是语言规范(请参阅此处)的摘录,来自描述条件表达式的返回值的部分:

否则,如果第二个和第三个操作数具有可转换为数值类型的类型 (§5.1.8),则存在以下几种情况:

最后一种情况是(我在这里省略了其他情况):

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

以下是与二进制数字促销相关的其他规范:

加宽基元转换 (§5.1.2) 应用于转换以下规则指定的任一或两个操作数:

  • 如果任一操作数的类型为双精度型,则另一个操作数将转换为双精度型。

这是第一种情况(以下情况被省略)。 总是赢家。double

因此,无论条件表达式中的第 2 个和第 3 个操作数的顺序如何,表达式的返回类型都将提升为 。double


答案 2

简而言之,三元运算符与涉及数值类型提升的其他运算符没有什么不同。

当您有类似的东西时,您希望它打印,因为输出中使用的操作数受数字类型升级的影响。System.out.println(1 + 1.0)2.0

它与三元运算符完全相同:在执行相同的数值类型升级后将打印,如果表达式为 .System.out.println(true ? 1 : 1.0)1.01 + 1.0

它之所以这样工作,原因很简单:运算符结果的类型应该在编译时知道,而其实际结果在运行时确定。