为什么将三元语句中的空值赋给布尔变量会抛出NPE?

时间:2014-10-18 19:11:20

标签: java nullpointerexception ternary-operator

我有一部分代码如下:

public static void main(String[] args) throws Exception {
    String trueValue = Boolean.TRUE.toString();
    String fieldValue = null;
    Boolean defaultValue = null;

    Boolean value = (fieldValue != null ? trueValue.equalsIgnoreCase(fieldValue) : defaultValue);

    System.out.println(value);
}

defaultValue不等于null时代码正常,但当defaultValuenull时,JVM会抛出NullPointerException。此代码使用jdk 1.6.45编译。

为什么我得到这个例外?

3 个答案:

答案 0 :(得分:13)

Java language specification说:

  

如果第二个和第三个操作数之一是基本类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,那么类型条件表达式是T

答案 1 :(得分:9)

这是三元运营商。因为第一个选项trueValue.equalsIgnoreCase(fieldValue)是布尔值,所以它似乎假设第二个选项defaultValue是布尔值而不是可空的Boolean。这很奇怪,但这似乎正在发生的事情。如果您将第一个选项转换为Boolean,则错误消失:

Boolean value = (fieldValue != null ? (Boolean) trueValue.equalsIgnoreCase(fieldValue) : defaultValue);

答案 2 :(得分:8)

来自JLS: 15.25. Conditional Operator ? :

  

如果第二个和第三个操作数之一是基本类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,那么类型条件表达式是T

Aka:当第2和第3个操作数是原始的盒装参考类型时,结果被认为是原始类型。在操作结束时,你再次装箱,但到那时你已经尝试将null分配给基本类型 - 这是不可能的。

String#equalsIgnoreCase的签名是......

public boolean equalsIgnoreCase