2011-09-07 119 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的原因顯而易見。