2011-09-07 73 views
0

有发生,当我执行下面的代码一件奇怪的事情:NullPointerException异常时数

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

    /* ... */ 
} 

有时我看到在日志中一个NullPointerException在分配行,我不明白为什么会发生。任何想法?

+2

如果输入不能为空,则使用'long'。 – starblue

回答

1

inLong大概是null。然后,您尝试分配一个null引用并将其取消装入基本类型。

+0

试图在我的机器上为long分配一个长度为'null'的值,只是为了确保。它的确会导致NullPointerException。 –

2

您传入null。检查你传递什么

1

因为inLong可以为空,也不会被自动映射到0
我猜你想做的事是这样的:

theNumber = 0; // or Long.MIN_VALUE or Long.MAX_VALUE or whatever you prefer 
if (inLong != null) { 
    theNumber = inLong; 
} 
// ... 
+1

谢谢,但我不认为映射到0将在这种情况下适当的解决方案... –

+0

这就是为什么我猜对了:)我通常使用'MIN_VALUE'或'NaN'为无效数字,但它高度依赖于上下文。 –

+0

MIN_VALUE或MAX_VALUE与0差别不大 - 您可以使用long参数(请参阅下面的答案)。使用NaN更好,但是你必须以完全不同的方式处理null,以避免另一个异常... – DaveFar

0

这是因为inLong参数空值。 无论您何时将Long对象分配给long变量,Java都会自动尝试将其拆箱为正确的类型,但如果Long变量的值为null,则它会失败。

只需在该赋值之前放置一个空检查并且您将摆脱该错误,但您可能必须引发异常或适当地处理空参数。

2

对于long theNumber = inLong;,通过隐式调用inLong.longValue()来获取inLong的long值。这被称为自动拆箱(有时更通用的自动装箱)。当inLong为null时,您就会得到一个NullPointerException,就像调用null上的任何其他方法一样。

因此,你应该考虑一些替代的:

如果你不需要一个未定义的值,你应该确保调用者永远传递空,并通过坚持这一点:

private void doStuff(Long inLong) { 
    assert inLong != null; 
    long theNumber = inLong; 
    /* ... */ 
} 

(或使用a Nonnull-Checker)。如果该方法是公开的,你不能确保空不通过,而这样做:

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类型的参数(见上)。

0

如果inLong为空,那么NPE就是预期的行为。

long theNumber = inLong; 

是语义上等同于

long theNumber = inLong.longValue(); 

这应该能让NPE的原因显而易见。