2011-10-18 29 views
0

這段代碼爲什麼會導致NPE? Findbugs給我的提示,這可能會發生,有時它確實:-)Java:unary if - npe

任何想法?

public Integer whyAnNPE() { 
    return 1 == 2 ? 1 : 1 == 2 ? 1 : null; 
} 
+6

這不是Java - 它是什麼語言? –

+0

我完成了這個例子。 – CannyDuck

+1

它仍然不是Java,但現在很明顯,爲什麼它給你NPE「有時」 –

回答

4

編輯:當我寫這個答案時,問題中的代碼不存在。

這裏的另一種方法,使之更加清晰略:

public static Integer maybeCrash(boolean crash) { 
    return true ? (crash ? null : 1) : 0; 
} 

重要的一點是,我們有條件表達式在這裏。由於在section 15.25中指定的類型確定的最後一個要點,內部的類型爲Integer

在這一點上,我們已經有了一個情況是這樣的:現在

public static Integer maybeCrash(boolean crash) { 
    Integer tmp = null; 
    return true ? tmp : 0; 
} 

剩餘條件表達式的,先前子彈一點也適用,並且執行binary numeric promotion。作爲第一步,這又調用unboxing - 失敗。

換言之,條件是這樣的:

condition ? null-type : int 

涉及潛在拳擊intInteger,但條件是這樣的:

condition ? Integer : int 

涉及潛在拆箱的Integerint


原來的答覆

這是一個相當簡單的例子實際上是有效的Java:

public class Test { 
    public static void main(String[] args) { 
     int x = args.length == 0 ? 1 : null; 
    } 
} 

這實際上是:

int tmp; 
if (args.length == 0) { 
    tmp = 1; 
} else { 
    Integer boxed = null; 
    tmp = boxed.intValue(); 
} 

顯然這裏的拆箱一步將砰的一聲。基本上,這是因爲通過拆箱將隱式表達式隱式轉換爲Integer,並從Integer轉換爲int

+0

我不明白這是如何適用於此。他正在返回一個'Integer'對象,所以null不會被解除封裝?他必須將它分配給一個'int',在這種情況下函數不是帶有bug的部分(我的意思是返回一個返回整數的方法返回null是完美的罰款) – Voo

+0

@Voo:不,因爲條件表達式的類型仍然是int - 然後再次裝箱。當我回答時,問題中的代碼不存在 - 我現在編輯。 –

+0

@Voo:看看它現在是否更有意義:) –

0

原始數據類型(int,long,float,double等)不能爲null,只有對象可以爲null。此外,查看方法的完整簽名非常有用,而不是僞代碼