<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 9.6 用finally清除 無論一個異常是否在`try`塊中發生,我們經常都想執行一些特定的代碼。對一些特定的操作,經常都會遇到這種情況,但在恢復內存時一般都不需要(因為垃圾收集器會自動照料一切)。為達到這個目的,可在所有異常控制器的末尾使用一個`finally`從句(注釋④)。所以完整的異常控制小節象下面這個樣子: ``` try { // 要保衛的區域: // 可能“拋”出A,B,或C的危險情況 } catch (A a1) { // 控制器 A } catch (B b1) { // 控制器 B } catch (C c1) { // 控制器 C } finally { // 每次都會發生的情況 } ``` ④:C++異常控制未提供`finally`從句,因為它依賴構造器來達到這種清除效果。 為演示`finally`從句,請試驗下面這個程序: ``` //: FinallyWorks.java // The finally clause is always executed public class FinallyWorks { static int count = 0; public static void main(String[] args) { while(true) { try { // post-increment is zero first time: if(count++ == 0) throw new Exception(); System.out.println("No exception"); } catch(Exception e) { System.out.println("Exception thrown"); } finally { System.out.println("in finally clause"); if(count == 2) break; // out of "while" } } } } ///:~ ``` 通過該程序,我們亦可知道如何應付Java異常(類似C++的異常)不允許我們恢復至異常產生地方的這一事實。若將自己的`try`塊置入一個循環內,就可建立一個條件,它必須在繼續程序之前滿足。亦可添加一個`static`計數器或者另一些設備,允許循環在放棄以前嘗試數種不同的方法。這樣一來,我們的程序可以變得更加“健壯”。 輸出如下: ``` Exception thrown in finally clause No exception in finally clause ``` 無論是否“拋”出一個異常,`finally`從句都會執行。 ## 9.6.1 用`finally`做什么 在沒有“垃圾收集”以及“自動調用析構器”機制的一種語言中(注釋⑤),`finally`顯得特別重要,因為程序員可用它擔保內存的正確釋放——無論在`try`塊內部發生了什么狀況。但Java提供了垃圾收集機制,所以內存的釋放幾乎絕對不會成為問題。另外,它也沒有構造器可供調用。既然如此,Java里何時才會用到`finally`呢? ⑤:“析構器”(Destructor)是“構造器”(Constructor)的反義詞。它代表一個特殊的函數,一旦某個對象失去用處,通常就會調用它。我們肯定知道在哪里以及何時調用析構器。C++提供了自動的析構器調用機制,但Delphi的Object Pascal版本1及2卻不具備這一能力(在這種語言中,析構器的含義與用法都發生了變化)。 除將內存設回原始狀態以外,若要設置另一些東西,`finally`就是必需的。例如,我們有時需要打開一個文件或者建立一個網絡連接,或者在屏幕上畫一些東西,甚至設置外部世界的一個開關,等等。如下例所示: ``` //: OnOffSwitch.java // Why use finally? class Switch { boolean state = false; boolean read() { return state; } void on() { state = true; } void off() { state = false; } } public class OnOffSwitch { static Switch sw = new Switch(); public static void main(String[] args) { try { sw.on(); // Code that can throw exceptions... sw.off(); } catch(NullPointerException e) { System.out.println("NullPointerException"); sw.off(); } catch(IllegalArgumentException e) { System.out.println("IOException"); sw.off(); } } } ///:~ ``` 這里的目標是保證`main()`完成時開關處于關閉狀態,所以將`sw.off()`置于`try`塊以及每個異常控制器的末尾。但產生的一個異常有可能不是在這里捕獲的,這便會錯過`sw.off()`。然而,利用`finally`,我們可以將來自`try`塊的關閉代碼只置于一個地方: ``` //: WithFinally.java // Finally Guarantees cleanup class Switch2 { boolean state = false; boolean read() { return state; } void on() { state = true; } void off() { state = false; } } public class WithFinally { static Switch2 sw = new Switch2(); public static void main(String[] args) { try { sw.on(); // Code that can throw exceptions... } catch(NullPointerException e) { System.out.println("NullPointerException"); } catch(IllegalArgumentException e) { System.out.println("IOException"); } finally { sw.off(); } } } ///:~ ``` 在這兒,`sw.off()`已移至一個地方。無論發生什么事情,都肯定會運行它。 即使異常不在當前的`catch`從句集里捕獲,`finally`都會在異常控制機制轉到更高級別搜索一個控制器之前得以執行。如下所示: ``` //: AlwaysFinally.java // Finally is always executed class Ex extends Exception {} public class AlwaysFinally { public static void main(String[] args) { System.out.println( "Entering first try block"); try { System.out.println( "Entering second try block"); try { throw new Ex(); } finally { System.out.println( "finally in 2nd try block"); } } catch(Ex e) { System.out.println( "Caught Ex in first try block"); } finally { System.out.println( "finally in 1st try block"); } } } ///:~ ``` 該程序的輸出展示了具體發生的事情: ``` Entering first try block Entering second try block finally in 2nd try block Caught Ex in first try block finally in 1st try block ``` 若調用了`break`和`continue`語句,`finally`語句也會得以執行。請注意,與作上標簽的`break`和`continue`一道,`finally`排除了Java對`goto`跳轉語句的需求。 ## 9.6.2 缺點:丟失的異常 一般情況下,Java的異常實現方案都顯得十分出色。不幸的是,它依然存在一個缺點。盡管異常指出程序里存在一個危機,而且絕不應忽略,但一個異常仍有可能簡單地“丟失”。在采用`finally`從句的一種特殊配置下,便有可能發生這種情況: ``` //: LostMessage.java // How an exception can be lost class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } } class HoHumException extends Exception { public String toString() { return "A trivial exception"; } } public class LostMessage { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) throws Exception { LostMessage lm = new LostMessage(); try { lm.f(); } finally { lm.dispose(); } } } ///:~ ``` 輸出如下: ``` A trivial exception at LostMessage.dispose(LostMessage.java:21) at LostMessage.main(LostMessage.java:29) ``` 可以看到,這里不存在`VeryImportantException`(非常重要的異常)的跡象,它只是簡單地被`finally`從句中的`HoHumException`代替了。 這是一項相當嚴重的缺陷,因為它意味著一個異常可能完全丟失。而且就象前例演示的那樣,這種丟失顯得非常“自然”,很難被人查出蛛絲馬跡。而與此相反,C++里如果第二個異常在第一個異常得到控制前產生,就會被當作一個嚴重的編程錯誤處理。或許Java以后的版本會糾正這個問題(上述結果是用Java 1.1生成的)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看