簡體   English   中英

finally 塊中的代碼和 finally 塊之后的代碼有什么區別?

[英]What's the difference between code inside finally block and code after finally block?

我想知道 finally 塊中的代碼和 finally 塊之后的代碼有什么區別

一個小測試程序顯示了差異:

public class FinallyTest {

    public static void main(String[] args) throws Exception {
        try {
            boolean flag = true;
            if (flag) {
                throw new Exception("hello");
            }
        } finally {
            System.out.println("this will get printed");
        }
        System.out.println("this won't show up");
    }
}

程序拋出一個異常,執行程序的 JVM 捕獲它並打印出來。

寫入控制台的內容是:

this will get printed
Exception in thread "main" java.lang.Exception: hello
    at snippet.FinallyTest.main(FinallyTest.java:7)

一旦拋出異常,該線程將執行的唯一事情(直到異常被 JVM 捕獲)是 finally 塊(其中異常離開 finally 所屬的 try 塊)。

如果 catch 塊重新拋出異常(或拋出一個新異常),則執行 finally 塊。 finally 塊之后的任何內容都不會被執行。

finally 塊總是在 try 塊退出時執行。 這確保即使發生意外異常也能執行 finally 塊。 但 finally 不僅僅用於異常處理——它允許程序員避免通過 return、continue 或 break 意外繞過清理代碼。 將清理代碼放在 finally 塊中始終是一個好習慣,即使沒有預料到異常也是如此。 - http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

如果在 catch 塊上拋出異常,或者在 try 塊上返回某些內容,它將執行 finally 塊。 如果不在 finally 塊上(在 try/catch/finally 之后),它將無法工作。 這里有一個簡單的例子供您理解:在沒有 finally 塊的情況下嘗試它,您將看到它打印消息“正在關閉資源...”的行將永遠不會被執行。

try {
    return "Something";
} catch (Exception e) {
    throw e;
} finally {
    System.out.println("Closing resources (Connections, etc.)...");//This will always execute
}

在這里,我在上面提供的示例中添加了更多內容,將來可能會對某人有所幫助,希望能避免一些混淆。

開始吧。

實際上,這取決於程序的流程控制。 這意味着如果程序的編寫方式是,如果您的代碼正在處理 try 塊中拋出的異常,並且您在 catch 塊中處理它們,那么 finally 塊之后的代碼將在 finally 塊中的代碼之后執行堵塞。

示例 1:此處異常已處理,因此執行 finally 塊之后的代碼。

public class TestFinally {

    public static void main(String[] args) throws Exception {
        try {
            boolean flag = true;
            if (flag) {
                throw new Exception("hello");
            }
        } 
        catch(Exception e){
            System.out.println("catch will get printed");   
        }
        finally {
            System.out.println("this will get printed");
        }
        System.out.println("this won't show up");
    }
}

結果:

catch will get printed
this will get printed
this won't show up

示例 2:如果 try 塊中的異常沒有像上面 Nathan 所說的那樣正確處理,則 finally 塊之后的代碼不會被執行。

public class TestFinally {

    public static void main(String[] args) throws Exception {
        try {
            boolean flag = true;
            if (flag) {
                throw new Exception("hello");
            }
        } 
        // not handling the exception thrown above
        /*catch(Exception e){
            System.out.println("catch will get printed");   
        }*/
        finally {
            System.out.println("this will get printed");
        }
        System.out.println("this won't show up");
    }
}

結果:

this will get printed
Exception in thread "main" java.lang.Exception: hello
    at com.test.TestFinally.main(TestFinally.java:36)

總之,總而言之, finally塊中的代碼總是被執行,除非在某些情況下線程在finally塊之前被停止或殺死,或者在 try 塊中編寫了任何退出程序的情況下。 而 finally 之后的代碼取決於在 try-catch-finally 塊中編寫的代碼和異常處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM