执行以下代码时发生了一件奇怪的事情:
private void doStuff(Long inLong) {
long theNumber = inLong;
/* ... */
}
有时我在分配行的日志中看到NullPointerException,我无法理解为什么会发生这种情况。有什么想法吗?
答案 0 :(得分:2)
你传入了null。检查你传递的内容。
答案 1 :(得分:2)
对于long theNumber = inLong;
,通过隐式调用inLong.longValue()
获取inLong的long值。这称为自动拆箱(有时更通用的自动装箱)。当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对象,你当然可以使用long
类型的参数并在doStuff
内进行(自动)装箱来获得一个相应的Long对象。
如果确实需要未定义的值,则应检查并执行必要的操作:
private void doStuff(Long inLong) {
if (inLong == null) {
handleUndef();
} else {
long theNumber = inLong;
/* ... */
}
}
我认为将值设置为0而不是更精细handleUndef()
是可疑的,因为那时你可以首先使用long类型的参数(见上文)。
答案 2 :(得分:1)
inLong可能是null
。然后,您尝试分配null
引用并将其解压缩为基本类型。
答案 3 :(得分:1)
因为inLong
可以为null并且不会自动映射到0
我想你想要做的是:
theNumber = 0; // or Long.MIN_VALUE or Long.MAX_VALUE or whatever you prefer
if (inLong != null) {
theNumber = inLong;
}
// ...
答案 4 :(得分:0)
那是因为inLong参数为null。
每当您将Long
对象分配给long
变量时,Java会自动尝试将其解包为正确的类型,但如果Long变量的值为null,则会失败。
只需在该分配之前进行空检查,您就可以摆脱该错误,但您可能必须提出异常或适当处理null参数。
答案 5 :(得分:0)
如果inLong为null,那么NPE就是预期的行为。
long theNumber = inLong;
在语义上等同于
long theNumber = inLong.longValue();
应该使NPE的原因显而易见。