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

Mic*_*ail 11 java ternary-operator nullpointerexception

我有一部分代码像这样:

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);
}
Run Code Online (Sandbox Code Playgroud)

defaultValue不等于null代码工作正常,但如果defaultValuenull在JVM抛出一个NullPointerException.此代码使用jdk 1.6.45编译.

为什么我得到这个例外?

Ser*_*tin 13

Java语言规范说:

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


khe*_*ood 9

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

Boolean value = (fieldValue != null ? (Boolean) trueValue.equalsIgnoreCase(fieldValue) : defaultValue);
Run Code Online (Sandbox Code Playgroud)


Jer*_*vel 8

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

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

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

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

public boolean equalsIgnoreCase
Run Code Online (Sandbox Code Playgroud)

  • +1,虽然"已经尝试将`null`分配给基本类型"将更好地写为"已经尝试**unbox**`null`到基本类型",或者可能是"已经隐式调用`booleanValue" )```null`引用". (2认同)