返回类型对象的方法中的java NullPointerException
为什么下面的语句会抛出NullPointerException?:
public static Object myTest() {
boolean x = false;
boolean y = false;
return x && y ? new Object() : x ? x : y ? y : null;
}
public static void main(String [ ] args) {
myTest();
}
我知道如果我执行以下任一操作,代码将不会抛出NullPointerException:
A)
public static Object myTest() {
boolean x = false;
boolean y = false;
return x && y ? new Object() : x ? x : y ? y : (Object) null;
}
public static void main(String [ ] args) {
myTest();
}
B)
public static Object myTest() {
Boolean x = false;
Boolean y = false;
return x && y ? new Object() : x ? x : y ? y : null;
}
public static void main(String [ ] args) {
myTest();
}
此外,如果我完全更改代码并执行以下操作,它也会起作用:
public static Object myTest() {
boolean x = false;
boolean y = false;
if(x && y) {
return new Object();
} else if(x) {
return x;
} else if(y) {
return y;
} else {
return null;
}
}
public static void main(String [ ] args) {
myTest();
}
我猜编译器正在进行某种优化,不知怎么搞砸了?我假设这是某种类型的强制转换问题,但为什么在这种情况下它会抛出NullPointerException而不是ClassCastException?任何关于为什么会发生这种情况的信息都将不胜感激
提前谢谢
# 1 楼答案
如果为可读性添加一些括号:
可以看到,在
y ? y : null
处,编译器将尝试取消null
的装箱(以便类型匹配),从而引发NPE# 2 楼答案
(此代码不可读,可能应该避免使用。)但要真正回答: 如上所述,推理与自动装箱和取消装箱以及编译器进行检查有关。就好像你写了
boolean b = (Boolean) null
,在运行时会抛出一个NPE在示例A中,您显式地将其强制转换为对象,因此没有添加自动装箱
在示例B中,所有内容都已经是一个对象(布尔值是一个基本值,而布尔值是一个对象),所以再次强调,没有装箱或拆箱
最后,在示例C中,根本没有解装箱,而是在返回结果时将其装箱。(if-else分支允许编译器单独检查每个分支,而不是三元运算符,后者需要计算出整个语句,然后为整个语句分配一个类型。这与语句与表达式以及Java自动装箱和类型检查规则中的许多奇怪之处有关。)
(如果您尝试不兼容的强制转换,例如:
(Boolean) 7
,则强制转换问题会在编译时发生,如果您执行以下操作,则会在运行时发生: