三元运算符

为什么以下代码的输出是9.0而不是9? 如果三元运算符只是if-else分支的简短forms,那么为什么java编译器将int提升为double?

public class Ternary { public static void main(String args[]) { int a = 5; System.out.println("Value is - " + ((a < 5) ? 9.9 : 9)); } } 

如果三元运算符只是if-else分支的简短forms,那么为什么java编译器将int提升为double?

条件表达式具有单个类型,第二个和第三个操作数都将根据需要进行转换。 JLS提供了确定表达式类型的规则,由于自动取消装箱,这些规则稍微复杂一些。

条件运算符只是if / else结构的简写,但不是我认为你预期的那种简写。 所以你的代码等同于:

 double value; if (a < 5) { value = 9.9; } else { value = 9; } System.out.println("Value is - " + value); 

不是简短的:

 if (a < 5) { System.out.println("Value is - " + 9.9); } else { System.out.println("Value is - " + 9); } 

有关更多详细信息,请参阅Java语言规范的15.25节 。

因为在这种conditional operator的类型(是,它是条件运算符而不是三元运算符 )将是第3个操作数的提升类型,因为第2和第3个操作数的类型不同。

这清楚地列在JLS Secion – 15.25中 : –

否则,如果第二个和第三个操作数具有可转换的类型(第5.1.8节)到数字类型,则有几种情况:

  • 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则则条件表达式的类型为short。

  • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型T中表示,那么条件表达式的类型是T.

  • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型U中表示,这是应用拆箱的结果转换为T,则条件表达式的类型为U.

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

请参阅最后一点,这是有用的。 因此,在这种情况下,作为binary numeric promotion的规则 – 参见JLS第5.6.2节 : –

  • 如果任一操作数的类型为double,则另一个操作数转换为double。

因为表达式的类型整体是double ,因为运算符的一个操作数是double 。 包含三元组的表达式的类型由操作数决定,操作数必须是相同的类型。 在表达式的情况下, 9被强制为double ,使其与9.9类型相同。

实际上,三元运算符并不严格地说是if / else的简短forms,因为它在需要时执行类型转换。 特别是在您的情况下, JLS 15.25要求:

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

如果您点击§5.6.2的链接:

如果任一操作数的类型为double,则另一个操作数转换为double。

Java需要在编译时知道结果的类型。 因此,当这个三元运算符可以产生int或double时,编译器选择double作为结果类型。