这里有点奇怪:
Integer oddity(boolean b1, boolean b2) {
return b1 ? 0 : b2 ? 1 : null;
}
这将失败,NullPointerException
如果b1
并且b2
是错误的。但是这个:
Integer oddity(boolean b1) {
return b1 ? 0 : null;
}
b1
为假时不抛出 NPE 。
为什么是这样?
这里有点奇怪:
Integer oddity(boolean b1, boolean b2) {
return b1 ? 0 : b2 ? 1 : null;
}
这将失败,NullPointerException
如果b1
并且b2
是错误的。但是这个:
Integer oddity(boolean b1) {
return b1 ? 0 : null;
}
b1
为假时不抛出 NPE 。
为什么是这样?
正如您可能想象的NullPointerException
那样,第一种情况是隐式拆箱的结果。这一切都在 JLS Sec 15.25中描述;但是规则很复杂,并且有一些棘手的方面。
这里令人惊讶的是:
System.out.println(b ? 0 : null);
不一样
Integer v = null;
System.out.println(b ? 0 : v);
Integer
:0
被装箱为Integer.valueOf(0)
。因此,该语句将正常完成,打印0
或null
。int
: v
is unboxed to 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;
}