5

在以下内联条件中,人们可能期望分别打印一个整数和一个双精度:

System.out.println(true ? 0 : 0.0);
System.out.println(false ? 0 : 0.0);
System.out.println(true ? new Integer(0) : new Double(0.0));
System.out.println(true ? 0 : "");

相反,当它们一起出现时,它们都被打印为双精度:

 0.0
 0.0
 0.0
 0

为什么数字与内联条件中的其他数字一起出现时会自动转换?

编辑:如果发生这种情况是因为System.out.println超载是什么情况:

list.add(true ? 0 : 0.0);
list.add(false ? 0 : 0.0);
list.add(true ? new Integer(0) : new Double(0.0));
list.add(true ? 0 : "");
System.out.println(list);

输出:

[0.0, 0.0, 0.0, 0]
4

4 回答 4

16

为什么数字与内联条件中的其他数字一起出现时会自动转换?

条件表达式必须具有单一结果类型,并且该类型用于确定System.out.println要使用的重载。重载总是在编译时确定,编译器根据选择的条件为表达式采用两条完全独立的路径真的很尴尬。

如果您根据条件做两件不同的事情,请使用if. 如果您想根据条件在两个值之间选择一种结果类型,那么条件运算符是完美的。

编辑:这里有趣的案例,IMO,是第三个。编译器可以选择不执行任何转换,只调用println(Object). 为了表明它没有这样做,这里有一个单独的测试:

Object x = true ? new Integer(0) : new Double(0.0);
System.out.println(x.getClass());

这会打印出来class java.lang.Double- 如果您查看字节码,您会看到它正在拆箱,int然后将其重新装箱为Double. 有关如何确定的详细信息,请参阅JLS 的第 15.25 节

于 2012-04-04T18:33:56.847 回答
4

条件运算符的双方必须兼容才能参与相同的三元运算。根据Java Language Specification 15.25,在您的情况下

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

通常,语言遵循一长串规则来得出三元条件运算符的结果类型。如果您需要更多详细信息,请阅读语言规范。

于 2012-04-04T18:37:18.600 回答
0

已编辑 因为println超载。它必须解析为其中一种形式,并选择捕获两者的最小类型(第一个 2 示例的 int 和 double ): void println(double x)

于 2012-04-04T18:34:01.567 回答
0

使用普通类型。0可以无损转换为double。(cond) 的结果?res1 : res2 必须是一种返回类型。

于 2012-04-04T18:35:20.127 回答