当我执行以下代码时发生了一件奇怪的事情:
private void doStuff(Long inLong) {
long theNumber = inLong;
/* ... */
}
有时我在分配行的日志中看到 NullPointerException,但我不明白为什么会发生这种情况。任何想法?
当我执行以下代码时发生了一件奇怪的事情:
private void doStuff(Long inLong) {
long theNumber = inLong;
/* ... */
}
有时我在分配行的日志中看到 NullPointerException,但我不明白为什么会发生这种情况。任何想法?
你传入了null。检查你传入的内容。
因为long theNumber = inLong;
, inLong 的 long 值是通过隐式调用来获取的inLong.longValue()
。这称为自动拆箱(有时更一般的自动装箱)。当 inLong 为 null 时,您将因此得到 NullPointerException,就像在 null 上调用任何其他方法一样。
因此,您应该考虑一些替代方案:
如果您不需要未定义的值,则应确保调用者永远不会传递 null 并通过以下方式断言:
private void doStuff(Long inLong) {
assert inLong != null;
long theNumber = inLong;
/* ... */
}
(或使用Nonnull-Checker)。如果该方法是公开的,并且您不能确定没有传递 null,请执行以下操作:
public void doStuff(Long inLong) {
if (inLong == null) { throw new IllegalArgumentException(); }
long theNumber = inLong;
/* ... */
}
如果您既不需要未定义的值,也不需要在集合(或任何其他通用参数)中使用该值,请改用该方法private void doStuff(long inLong)
。如果您确实需要 Long 对象,当然,您仍然可以使用 type 的参数long
并在内部进行(自动)装箱doStuff
以获得相应的 Long 对象。
如果您确实需要未定义的值,您应该检查它并执行必要的操作:
private void doStuff(Long inLong) {
if (inLong == null) {
handleUndef();
} else {
long theNumber = inLong;
/* ... */
}
}
在我看来,仅将值设置为 0 而不是更详细的值handleUndef()
是可疑的,因为那时您可以首先使用 long 类型的参数(见上文)。
inLong 大概是null
. 然后您尝试分配一个null
引用并将其拆箱为原始类型。
因为inLong
可以为null,不会自动映射到0。
我猜你想要做的是:
theNumber = 0; // or Long.MIN_VALUE or Long.MAX_VALUE or whatever you prefer
if (inLong != null) {
theNumber = inLong;
}
// ...
那是因为 inLong 参数为空。每当您将Long
对象分配给long
变量时,Java 都会自动尝试将其拆箱为正确的类型,但如果 Long 变量的值为 null,则会失败。
只需在该分配之前进行一次空检查,您就会摆脱该错误,但您可能必须引发异常或适当地处理空参数。
如果 inLong 为空,则 NPE 是预期的行为。
long theNumber = inLong;
在语义上等价于
long theNumber = inLong.longValue();
这应该使 NPE 的原因显而易见。