2014-05-13 84 views
3

在JAVA中進行異常處理練習時,我對各種事情感到有點困惑。基本上我不明白的是程序的流程是什麼時候遇到異常。我想了解在以下情況下程序的流程是如何發生的,以及我對這些概念的理解是對還是錯。瞭解JAVA中的關鍵字

public void myFunction(){ 

    try{ 

      //Some code...... 

     }catch(Exception e1){ 

      //If this Exception is occured handle it here. 

     }catch(Exception e2){ 

      //if this exception has occured then 

      throw new myException("whatever message required"); 
     } 

     finally{ 

      //code that has to be executed 
     } 

} 

現在有什麼我的理解是:

1.如果沒有例外的是隨後發生的代碼運行順利,最終在finally塊中的代碼被執行 2.如果異常發生E1則抓在第一個catch塊中,它被適當地處理,然後最終塊被執行。 3.如果發生異常e2,會發生什麼情況。在那個catch塊中,我們拋出一個新的異常。 那麼我調用myFunction的方法應該提供一些機制來處理這個異常?所以執行將轉移到調用方法的catch塊。右? 那麼myFunction()的「finally」塊會發生什麼?它會不會被執行呢? 程序如何發生?我真的很難找到當我們使用「扔」時會發生什麼。當我們使用它時會發生什麼?

+1

Look:e1和e2的類型都是相同的:異常,這就是catch(Exception e2)沒有機會執行的原因。 –

回答

4

見(您修改爲例):

try { 
    // Some code ... 
} 
catch(SomeException e1) { 
    // SomeException code ... 
} 
catch(SomeOtherException e2) { // SomeOtherException is NOT SomeException extension 
    throw new myException("whatever message required"); 
} 
finally { 
    // Some final code ... 
} 

執行的可能性:

1. No exception at all: 
    Some code executed 
    Some final code executed 
2. SomeException is thrown: 
    Some code (may be partially) executed 
    SomeException code executed 
    Some final code executed 
3. SomeOtherException is thrown: 
    Some code (may be partially) executed 
    Some final code executed 
    throw new myException("whatever message required"); 
4. SomeStrangeException is thrown 
    Some code (may be partially) executed 
    Some final code executed 
    System'll look for other try {} catch {} block to catch SomeStrangeException 
+0

因此,如果拋出的異常不會在後續的catch塊中處理,那麼首先finally塊會被執行,然後只有程序在調用堆棧中搜索異常是否被處理。 – neerajDorle

+0

@neerajDorle:是的,這是一個非常方便的行爲:首先清理資源,然後嘗試(可能徒勞)修改原因(未定義的例外) –

1

「我調用myFunction的方法應該提供一些機制來處理這個myException? 它應該,但編譯器會讓你這樣做,只有當myException擴展檢查的異常。無論發生什麼事,finally塊總會被執行。

+0

因此,如果拋出的異常在後續的catch塊中沒有處理,那麼finally塊將首先被執行,然後只有程序在調用堆棧上搜索異常是否被處理。 – neerajDorle

+0

是的,嘗試調試你的例子,看看如何流程 – Szarpul

0

你都不能想了解Java的異常是如何在運行時處理的一切都可以在Java Language Specification, section 11.3

從本質上講,在遇到異常時,可以發現,程序流程暫停,控制轉移到調用堆棧或者直到該異常被try/catch所捕獲,或者直到異常到達堆棧的底部,此時線程被終止。

所以,換句話說,「事情發生後,停止不管你在做什麼,去就近的catch塊匹配此異常,除非沒有catch塊存在,在這種情況下殺死線程」

在你的情況, e2將永遠不會發生,因爲全部例外已被第一個catch塊捕獲。如果您想要以不同的方式處理不同的例外情況,通常會使用多個catch區塊,例如例如,在一個塊中捕獲IOException,在另一個塊中捕獲NumberFormatException,例如,如果您正在解析文件中的數字。

您不必處理運行時異常(延伸到RuntimeException的異常)。您必須明確處理已檢查的例外(延伸Exception但不包括RuntimeException的例外)。

無論是否拋出異常,finally塊中的代碼都會被執行。

+0

請看看在第一個答案寫的修改後的代碼,並給出相應的答案.....還有一個問題:所以如果拋出異常不在後續的catch塊中處理,首先finally塊被執行,然後只有程序在調用堆棧中搜索異常是否被處理。 – neerajDorle

+0

我相信是這樣。在JVM開始向上調用堆棧之前,會執行'finally'塊。 – awksp

+0

謝謝,這是我想要的,請編輯你的答案 – neerajDorle

2

考慮下面的例子(Basicalliy你的例子只是充滿了一些真正的代碼,它被設計成拋出NullPointerException):

public class Exceptions { 

    public static void myMethod() { 
     try{ 
      String s = null; 
      s.length(); 
     } 
     catch(NumberFormatException e1){ 
      System.out.println("Something unexpected happend"); 
     } 
     catch(NullPointerException e2){ 
      throw new RuntimeException("Exactly what we want happened"); 
     } 
     finally{ 
      System.out.println("Finally Block"); 
     } 
    } 

    public static void main(String[] args){ 
     try{ 
      myMethod(); 
     } 
     catch(RuntimeException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

輸出這就是:

Finally Block 
java.lang.RuntimeException: Exactly what we want happened 
    at Exceptions.myMethod(Exceptions.java:14) 
    at Exceptions.main(Exceptions.java:23) 

所以你可以看到,在此之前,新的RuntimeException被交給調用方法最終塊被執行。否則,「Finally Block」輸出將在RuntimeException的堆棧跟蹤之後。

+0

Thankyou!它清除了我的困惑:) – neerajDorle