2011-07-06 58 views
30
class ThrowNull { 
    public static void main(String[] args) { 
     throw null; 
    } 
} 

我們知道拋出規則throw ThrowableInstance;,其中ThrowableInstance必須是Throwable類型或Throwable的子類的對象。爲什麼「throw null」不會在Java中創建編譯錯誤?

簡單類型(如int或char)以及非Throwable類(如String和Object)不能用作例外。 null是表示空值的特殊Java文字。

那麼爲什麼throw null;會在這段代碼中編譯?

+3

它爲什麼會導致編譯時錯誤? – BoltClock

+0

儘管目前Java編譯器本身並未將其標記爲問題(除非語言規範在未來某個時間發生變化),但顯然它是靜態檢查器(如「聲納」)的候選者,可以根除並指出開發商。也許開發人員想寫「return null」... –

+2

我們知道規則是調用'String a(){return null}'的結果必須是(子)類或String的對象。簡單的類,如Throwable或BigInteger不能用作字符串。空是表示空值的特殊Java文字。那爲什麼'返回null'不會產生任何編譯時錯誤????? !!!!我在這裏暴露你的雙重標準。爲什麼你抱怨'拋出null'而不是'return null'?因此我無法提出你的問題。它通過雙重標準過於局部化。 – Val

回答

54

按照language specification,一個throw陳述的定義爲:

throw Expression 

而且如果Expression計算結果爲null,然後NullPointerException被拋出。具體而言,

如果表達的評價正常完成,產生null值,則一個實例V」 NullPointerException類的被創建並拋出代替null

由於NullPointerException延伸RuntimeException,這是一個未經檢查的例外。這可以解釋爲什麼從這個結構中沒有報告編譯時錯誤。

5

編譯器有很多事情沒有檢查,它假定你做的事情有一個很好的理由,它可能不知道。它試圖防止的是開發人員犯的常見錯誤。

很可能有些人認爲這是

throw new NullPointerException(); 

Integer i = null; 
try { 
    i.intValue(); 
} catch (NullPointerException npe) { 
    System.err.println("Caught NPE"); 
    npe.printStackTrace(); 
} 

,並在Java 6的更新

try { 
    throw null; 
} catch (NullPointerException npe) { 
    System.err.println("Caught NPE"); 
    npe.printStackTrace(); 
} 

打印好淡手38

Caught NPE 
java.lang.NullPointerException 
    at Main.main(Main.java:9) 
+0

@DanielWerner即使是OutOfmemoryError和ThreadDeath也可以捕獲所有異常和錯誤。 ;)看我的例子。確切地說, –

2

在generel中,而不只是拋出。任何對象變量都可以賦值爲null。所以我們可以看到拋出並不是特例。它應該是?也許。它一致嗎?是。

3

我認爲,因爲空可以投入到任何類型的reference.so在編譯時,它沒有錯,如果你是拋出null而不是throwable。

+0

。你的方法返回一個String,可能返回null。爲什麼字符串變量可以爲null,但Throwable變量不能? OP絕對是短視的(x)或者執行雙重標準。 – Val

+0

這聽起來很不錯,但事實並非如此。看到接受的答案。 – Vlasec

相關問題