2013-07-29 43 views
9

为什么此代码有效?奇怪的Java行为。三元运算符

Float testFloat = null; 
Float f = true ? null : 0f; 

为什么会抛出异常?

Float testFloat = null; 
Float f = true ? testFloat : 0f; 

但奇怪的是,这种代码也运行成功,没有任何例外:

Float testFloat = null; 
Float f = testFloat; 

看来,爪哇三元运营商改变行为。任何人都可以解释为什么这是吗?

+0

我用JDK 7u25运行它,它没有抛出任何异常。 –

+0

第三个代码不能抛出异常:你声明一个变量,将其设置为null,然后声明另一个变量并将其设置为第一个为null的值。没有例外可以抛出 –

回答

13

的行为在指定JLS - Conditional Operator

如果第二和第三个操作数中的一个是原始类型T的,并且其他的类型是施加装箱转换的结果(§5.1.7)到T,那么条件表达式的类型是T

强调我的。因此,在2次情况

Float f = true ? testFloat : 0f; 

由于第三操作数是原始类型(T),则表达式的类型将是浮式 - T。所以,拆箱testFloat这也是目前null参考,float将导致NPE


对于1 ST情况下,相关部分是最后一个:

否则,第二和第三操作数分别为类型S1和S2的。假设T1是将装箱转换应用于S1所产生的类型,并让T2为将装箱转换应用于S2所得到的类型。条件表达式的类型是将捕获转换(第5.1.10节)应用于lub(T1,T2)(第15.12.2.7节)的结果。

因此,根据这样的:

null type - S1 
float  - S2 

null type - T1 (boxing null type gives null type) 
Float  - T2 (float boxed to Float) 

然后条件表达式类型变得 - Float。没有拆箱的null需要,因此没有NPE

+0

哦,我现在明白了! Thx你这么多的答案! – user2452103

+0

我无法找到确切的规则,为什么'真? null:0f'没问题。你能指出JLS中的那个部分吗?或者仅仅是“如果第二个和第三个操作数具有相同的类型(可能是空类型),那么这就是条件表达式的类型。”,其中'0f'被装箱到'Float'? –

+0

@Heuster。让我看看。 –