2009-07-10 74 views
7

考慮下面的代碼經過檢查異常

private int meth() 
{ 
    try 
    { 
     return 1; 
    } 
    catch(Exception ex) 
    { 
     return 2; 
    } 
    finally 
    { 
     return 3; 
    } 
} 

當aforeseen代碼被編譯,「異常」被視爲未經檢查的異常。這是編譯錯誤不occur.Consider我聲明我自己的異常「無法到達catch塊的例外是從來沒有在try塊拋出」,

class MyException extends Exception 
{ 
} 

,並在代碼

private int meth() 
{ 
    try 
    { 
     return 1; 
    } 
    catch(MyException me) 
    { 
     return 2; 
    } 
    finally 
    { 
     return 3; 
    } 
} 

在此使用它「無法訪問的catch塊MyException永遠不會在try塊中拋出」編譯錯誤發生。爲什麼在第一種情況下,「Exception」被視爲RuntimeException,在第二種情況下,即使「MyException」是「Exception」的子類,它將被視爲檢查異常。有人可以幫我解決這個問題嗎?

回答

4

只要編譯器知道你可以在任何時候獲取堆棧溢出異常,內存不足異常,算術異常或任何其他JVM生成的異常。另一方面,它可以靜態分析try區塊,看到MyException永遠不會拋出,所以它會拋出雙手。它知道它永遠不會被JVM拋出。

+0

這將是我的猜測 - 因爲它把JVM異常的異常,它可以拋出 - 但它知道一個用戶定義的異常不能被拋出,除非是在嘗試「拋」打電話的任何地方。 – nlaq 2009-07-10 04:15:27

12

此行爲的原因是Java語言中唯一未經檢查的異常是RuntimeException,它是子類。所有其他的異常和錯誤,包括你的異常和錯誤,因爲它只是Exception的子類(而不是RuntimeException)是檢查異常。

的原因,第一個代碼示例沒有得到由編譯器標記,但它使用的異常類作爲其catch語句,是因爲類層次的。由於所有的異常都是從異常派生的,所以你的代碼並沒有專門捕獲Exception,而是捕獲所有的異常並將它們轉換爲Exception的一個實例。因此,編譯器無法確定將在運行時捕獲的異常是否爲checked或unchecked異常。在第二個代碼塊中,被捕獲的異常無法成爲檢查異常,因此編譯器可以確定您的catch塊無法訪問。

+0

的確是一個更好的答案。 +1 – 2009-07-10 04:34:01

+0

+1 - 我要寫的只是...看異常繼承層次結構......它都在那裏:-) – Newtopian 2009-07-10 05:01:56

1

在Java中,unchecked(RuntimeExceptions)和checked異常都是從Exception派生的。

在你的榜樣,在第一種情況下,catch塊可以要麼抓一個RuintimeException(你得到好處的疑問在這裏)或任何檢查的異常,因此沒有抱怨沒有捕捉到的異常。

但是在因爲你已經明確提到的異常類型,它是一個檢查之一,這是不是在你的代碼的任何部分拋出,從而使錯誤的第二種情況。 這catch塊不適用於RTExceptions.In這種特殊情況下,你不會懷疑它的編譯器曾在你的第一個方案中受益。