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

我有一部分代码如下:

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编译。

为什么我得到这个例外?

Java语言规范说:

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

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

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

来自JLS:15.25。 条件运算符? :

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

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

String#equalsIgnoreCase的签名是……

 public boolean equalsIgnoreCase