为什么在Java自动转换数字中使用内联条件?

时间:2012-04-04 18:30:51

标签: java

在以下内联条件中,可能会分别打印一个整数和一个double:

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 个答案:

答案 0 :(得分: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。有关如何确定所有内容的详细信息,请参阅section 15.25 of the JLS

答案 1 :(得分:4)

条件运算符的两端必须兼容才能参与相同的三元运算。根据{{​​3}},根据您的情况

  

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

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

答案 2 :(得分:0)

<强> EDITED 因为println超载了。它必须解析为其中一种形式,并且它选择捕获两者的最小类型(前两个示例的int和double): void println(double x)

答案 3 :(得分:0)

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