Java 使用时出现意外的NullPointerException?:
这里有一点奇怪:Java 使用时出现意外的NullPointerException?:,java,conditional-operator,language-specifications,Java,Conditional Operator,Language Specifications,这里有一点奇怪: Integer oddity(boolean b1, boolean b2) { return b1 ? 0 : b2 ? 1 : null; } 如果b1和b2为false,则此操作将失败,并出现NullPointerException。但这是: Integer oddity(boolean b1) { return b1 ? 0 : null; } 当b1为false时不抛出NPE 这是为什么?正如您可能想象的那样,第一种情况下的NullPointerExcep
Integer oddity(boolean b1, boolean b2) {
return b1 ? 0 : b2 ? 1 : null;
}
如果b1
和b2
为false,则此操作将失败,并出现NullPointerException
。但这是:
Integer oddity(boolean b1) {
return b1 ? 0 : null;
}
当b1
为false时不抛出NPE
这是为什么?正如您可能想象的那样,第一种情况下的
NullPointerException
是隐式取消装箱的结果。这就是所描述的一切;但规则很复杂,而且有一些棘手的方面
令人惊讶的是:
System.out.println(b ? 0 : null);
不一样
Integer v = null;
System.out.println(b ? 0 : v);
- 第一种情况下的条件表达式的类型为
:将Integer
装箱为0
。因此,此语句将正常完成,打印Integer.valueOf(0)
或0
null
- 第二种情况下的条件表达式的类型为
:int
未绑定到v
。因此,此语句要么打印v.intValue()
,要么以0
失败NullPointerException
return Integer.valueOf(b1 ? 0 : (b2 ? Integer.valueOf(1) : null).intValue());
调用intValue()
时可能会失败;问题的第二个例子是:
return b1 ? Integer.valueOf(0) : null;
这不会失败
如果要返回0、1或null,最小的更改是显式地将
0
框起来:
return b1 ? Integer.valueOf(0) : b2 ? 1 : null;
这看起来很尴尬,因为0和1的表示方式不同。您也可以显式地将1装箱:
return b1 ? Integer.valueOf(0) : b2 ? Integer.valueOf(1) : null;
这是可行的,但很冗长,一些好心的同事(或者你,几个月后,当你回到这里,忘记了显式拳击的原因)会取消拳击,因为你不需要,对吗
就我个人而言——最近花了一些时间详细研究了条件运算符——我会选择完全避免它,而不会冒违反其奇怪类型规则的风险
if (b1) {
return 0;
} else if (b2) {
return 1;
} else {
return null;
}
好发现!拳击是错误的进一步证明;)