分配数字时出现NullPointerException

时间:2011-09-07 10:09:22

标签: java nullpointerexception autoboxing

执行以下代码时发生了一件奇怪的事情:

private void doStuff(Long inLong) {
    long theNumber = inLong;

    /* ... */
}

有时我在分配行的日志中看到NullPointerException,我无法理解为什么会发生这种情况。有什么想法吗?

6 个答案:

答案 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的原因显而易见。