2017-10-28 64 views
0

考慮以下方案:與Java SE 6(和以前的版本),更精確的重新拋出異常

class FirstException extends Exception {} 

class SecondException extends Exception {} 

class RethrowException { 
    public void rethrowMethod() throws FirstException, SecondException { 
      boolean flag = true; 
      try { 
       if(flag) 
        throw new FirstException(); 
       else 
        throw new SecondException(); 
      } 
      catch(Exception ex) { 
       throw ex; // does not compile "Unhandled exception type Exception" 
      } 
    } 
} 

此錯誤只是與Java SE 6(或以前的版本)是因爲,首先,當我們建立「catch」塊(catch(Exception ex)),由ex指定的異常對象的類型爲FirstException(或SecondException)。但是,當ex被重新拋出(throw ex),Java編譯器執行如下3項任務:

  1. 版本 「EX」 系統。
  2. 初始化新的異常對象,「EX」,其具有異常的類型
  3. 擲「EX」 - 這是異常的情況下,現在,不是FirstException(或SecondException)實例

因此,在Java SE 6中,我們不能使用「更精確地重新拋出異常」,因爲下面的原因。但是,在Java SE 7(或更高版本)中,我們可以這樣做,因爲當我們重新拋出ex時,運行時系統不會釋放並初始化新對象ex。它會檢查(找到)ex1 come from (the try block above), and so know that ex is an instance of FirstException or SecondException`。

我上面的解釋是否正確?

+0

我不能說這是你的解釋和哪部分是問題。 –

+0

我*能*告訴你,「爲什麼我可以在Java 7或更高版本上編譯這個,但不是Java 6或更低版本」(如果的確如此)與* runtime *行爲沒有任何關係。這將與*編譯器*有關,因爲它已經變得更加智能。 –

+0

這是真的在Java> 6編譯?它看起來像一個不好的做法..編輯:它,我看到這個例子來自Java文檔[鏈接](https://docs.oracle.com/javase/7/docs/technotes/guides/language/追趕multiple.html)。 – NickL

回答

2

通過在Java上的任何版本中捕獲異常並從catch塊中拋出異常,都不會創建新的異常實例。

在Java 6-,捕捉到的異常的類型被聲明爲Exceptioncatch塊,所以這是編譯器的想法被拋出。

在更高版本中,異常的類型被推斷爲僅限於可能從try塊中拋出。

+0

我不明白,當我檢查「ex」的類型(使用instanceof)時,我得到「FirstException」。因此,「ex」具有FirstException類型,爲什麼當我們重新運行時,運行時系統會拋出Exception類型,而它是FirstException? –

+0

@John'instanceof'是一個* runtime *的東西。該錯誤是*編譯時*的事情。編譯器很愚蠢。它沒有推斷出什麼是可能的,它只是看它被聲明爲什麼。在這種情況下,Java 7+稍微聰明一點。 – Bohemian

+0

我可以總結一下:「在Java SE 6-中,編譯器並不關心在重新拋出之前發生的所有事情,所以,當」ex「被重新拋出時,編譯器會拋出異常(它看起來是什麼聲明爲」ex「),雖然實際上,「ex」是FirstException ...是對的嗎? –