Java 为什么作为三元运算符的结果返回null(预期为布尔值)会编译?
我刚刚注意到的好奇心,而不是一个问题 我不允许写作Java 为什么作为三元运算符的结果返回null(预期为布尔值)会编译?,java,ternary-operator,Java,Ternary Operator,我刚刚注意到的好奇心,而不是一个问题 我不允许写作 public boolean x() { return null; } public boolean x() { return DEBUG ? true : null; } 或者这个: public boolean x() { if (DEBUG) { return true; } else { return null; } } 但是我被允许写作 public boolean x() { retur
public boolean x() {
return null;
}
public boolean x() {
return DEBUG ? true : null;
}
或者这个:
public boolean x() {
if (DEBUG) {
return true;
} else {
return null;
}
}
但是我被允许写作
public boolean x() {
return null;
}
public boolean x() {
return DEBUG ? true : null;
}
为什么会这样?(如果采用“else”分支,则似乎会抛出NPE。)三元运算符看到您有两个选项
true
和null
,因此它必须使用自动装箱并将自身(即条件运算符的结果)键入布尔值(反过来,通过返回
)再次自动解除绑定)
确切的规则有点复杂,你可以找到
在运行时,在取消装箱返回值期间,您会得到一个NullPointerException。状态如下:
条件表达式的类型确定如下:
如果第二个和第三个操作数具有相同的类型(可能是null类型),则这就是条件表达式的类型。
如果第二个和第三个操作数中的一个是基元类型T,而另一个的类型是对T应用装箱转换(§5.1.7)的结果,则条件表达式的类型是T
这意味着java允许null
,因为它可以用来生成Boolean
的实例,该实例可以取消绑定到Boolean
(有关更多信息,请阅读jls中的有关部分)。但是由于booleanValue>实例已初始化null
,因此对booleanValue()的调用
将导致空点异常
请参阅
条件表达式的类型确定如下:……如果第二个和第三个操作数中的一个为null类型,而另一个操作数的类型为引用类型,则条件表达式的类型为该引用类型
在运行时,首先计算条件表达式的第一个操作数表达式。如有必要,将对结果执行取消装箱转换
然后使用生成的布尔值选择第二个或第三个操作数表达式:
然后计算所选操作数表达式,并将结果值转换为由上述规则确定的条件表达式类型
这种转换可能包括装箱(§5.1.7)或拆箱(§5.1.8)转换
所以-本质上-你的null
被装箱成Boolean
谢谢@Thilo。澄清一下:问题是,为什么三元结构没有像其他两个例子一样被拒绝?@MichaelKay再次,只是出于curosity,你试过public Boolean x(){if(DEBUG){return true;}return null;}
?可能的重复?在java8中,它甚至更复杂。请参阅,但另一个不是引用类型。请阅读JLS中适用于此处的规则。