2016-10-10 72 views
5

在java中发现了一些奇怪的东西。java中的奇怪事物

代码:

System.out.println(System.getProperty("java.version")); 
System.out.println((true) ? (int)2.5 : 3.5); 
System.out.println((true) ? (int)2.5 : 3); 
System.out.println((true) ? (int)2.5 + "" : 3.5); 

结果:

 
1.8.0_40 
2.0 
2 
2 

这是什么?为什么整数值只有在false的值不是double或字符串值为true时才返回?为什么在第二行舍入由(int)强制转换工作,但双值返回呢?这是一个错误吗?

+0

不,这些东西不是bug。 – Jesper

+4

就编译器而言,整个'':'表达式只有一种类型,它通过找出两边共同的最窄类型来表示这一点。 –

+0

(我坦白,我很惊讶,最后一行编译,虽然。) –

回答

3

在示意性:

(true) ? (int)2.5 : 3.5 

     int  double 
      \  /
      double 

double的字面2.5被下采样到int 2,然后提升回double 2.0,因为这是条件表达式的类型。

4

https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25指定所有这些规则,这些规则的行为与观察到的输出完全一致。

整个三元表达式只有一种类型,这就是返回的内容,这就是System.out.println被调用的内容。如果您在该规范的表格中查找它,您会发现您提到的行中的类型将分别为doubleintObject

2

三元运算符具有常数返回类型。

JLS, section 15.25

否则,二进制数值提升(§5.6.2)被施加到操作数类型,以及条件表达式的类型是所述第二和第三操作数的提升的类型。

这意味着,在(true) ? (int)2.5 : 3.52.5转换为int,(向下),然后加宽到double

(true) ? (int)2.5 : 3中,int不需要被扩大至double,因为对方也是int

最后,在(true) ? (int)2.5 + "" : 3.5);,它不能被加宽,因为它已经被转换为String