为什么三元运算给出了nullpointer而ifelse对应的呢?

DKS*_*ore 15 java ternary-operator nullpointerexception

我在下面的一个实例中得到NullPointerException,而它的对应运行顺利.

public static void main(String[] args){
    System.out.println(withTernary(null, null)); //Null Pointer
    System.out.println(withIfElse(null, null));  //No Exception
}

private static Boolean withTernary(String val, Boolean defVal){
    return val == null ? defVal : "true".equalsIgnoreCase(val);
}

private static Boolean withIfElse(String val, Boolean defVal){
    if (val == null) return defVal;
    else return "true".equalsIgnoreCase(val);
}
Run Code Online (Sandbox Code Playgroud)

在线版

在线版本中的台词main相反,它输出nullwithIfElse,然后失败withTernary.

我正在使用以下java版本

java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
Run Code Online (Sandbox Code Playgroud)

Ale*_*ing 9

以下是规范(§15.25.2)中的相关引用:

布尔条件表达式是独立表达式(第15.2节).

布尔条件表达式的类型确定如下:

  • 如果第二个和第三个操作数都是类型Boolean,则条件表达式具有类型Boolean.

  • 否则,条件表达式具有类型boolean.

因此,整个表达式的类型被认为是boolean,并且Boolean值是自动装箱的,导致a NullPointerException.


正如评论中所提到的,为什么以下不会引发异常?

return val == null ? null : "true".equalsIgnoreCase(val);
Run Code Online (Sandbox Code Playgroud)

那么,上面的规范摘录特别适用于布尔条件表达式,这里指定(第15.25节):

如果第二个和第三个操作数表达式都是布尔表达式,则条件表达式是布尔条件表达式.

为了对条件进行分类,以下表达式是布尔表达式:

  • 具有类型或的独立形式(第15.2节)的表达式.booleanBoolean

  • 带括号的boolean表达式(第15.8.5节).

  • 类的类实例创建表达式(第15.9节)Boolean.

  • 方法调用表达式(第15.12节),其中所选择的最具体方法(第15.12.2.5节)具有返回类型booleanBoolean.
    (注意,对于泛型方法,这是在实例化方法的类型参数之前的类型.)

  • boolean条件表达式.

由于null不是布尔表达式,因此整个条件表达式不是布尔条件表达式.参考表15.2(稍后在同一节中),我们可以看到这样的表达式被认为具有Boolean类型,因此不会发生拆箱,也不会引发异常.


sfT*_*mas 7

val == null ? defVal : "true".equalsIgnoreCase(val)- 在这个表达式中,第三个参数是boolean,并且由于三元运算符必须有一个静态类型,它将尝试取消打包null,因此NPE.只有分配Boolean才会再次造成拳击.检查一下.