<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國際加速解決方案。 廣告
                ### [揭示細節](https://lingcoder.gitee.io/onjava8/#/book/15-Exceptions?id=%e6%8f%ad%e7%a4%ba%e7%bb%86%e8%8a%82) 為了研究 try-with-resources 的基本機制,我們將創建自己的 AutoCloseable 類: ~~~ // exceptions/AutoCloseableDetails.java class Reporter implements AutoCloseable { String name = getClass().getSimpleName(); Reporter() { System.out.println("Creating " + name); } public void close() { System.out.println("Closing " + name); } } class First extends Reporter {} class Second extends Reporter {} public class AutoCloseableDetails { public static void main(String[] args) { try( First f = new First(); Second s = new Second() ) { } } } ~~~ 輸出為: ~~~ Creating First Creating Second Closing Second Closing First ~~~ 退出 try 塊會調用兩個對象的 close() 方法,并以與創建順序相反的順序關閉它們。順序很重要,因為在這種情況下,Second 對象可能依賴于 First 對象,因此如果 First 在第 Second 關閉時已經關閉。 Second 的 close() 方法可能會嘗試訪問 First 中不再可用的某些功能。 假設我們在資源規范頭中定義了一個不是 AutoCloseable 的對象 ~~~ // exceptions/TryAnything.java // {WillNotCompile} class Anything {} public class TryAnything { public static void main(String[] args) { try( Anything a = new Anything() ) { } } } ~~~ 正如我們所希望和期望的那樣,Java 不會讓我們這樣做,并且出現編譯時錯誤。 如果其中一個構造函數拋出異常怎么辦? ~~~ // exceptions/ConstructorException.java class CE extends Exception {} class SecondExcept extends Reporter { SecondExcept() throws CE { super(); throw new CE(); } } public class ConstructorException { public static void main(String[] args) { try( First f = new First(); SecondExcept s = new SecondExcept(); Second s2 = new Second() ) { System.out.println("In body"); } catch(CE e) { System.out.println("Caught: " + e); } } } ~~~ 輸出為: ~~~ Creating First Creating SecondExcept Closing First Caught: CE ~~~ 現在資源規范頭中定義了 3 個對象,中間的對象拋出異常。因此,編譯器強制我們使用 catch 子句來捕獲構造函數異常。這意味著資源規范頭實際上被 try 塊包圍。 正如預期的那樣,First 創建時沒有發生意外,SecondExcept 在創建期間拋出異常。請注意,不會為 SecondExcept 調用 close(),因為如果構造函數失敗,則無法假設你可以安全地對該對象執行任何操作,包括關閉它。由于 SecondExcept 的異常,Second 對象實例 s2 不會被創建,因此也不會有清除事件發生。 如果沒有構造函數拋出異常,但在 try 的主體中可能拋出異常,那么你將再次被強制要求提供一個catch 子句: ~~~ // exceptions/BodyException.java class Third extends Reporter {} public class BodyException { public static void main(String[] args) { try( First f = new First(); Second s2 = new Second() ) { System.out.println("In body"); Third t = new Third(); new SecondExcept(); System.out.println("End of body"); } catch(CE e) { System.out.println("Caught: " + e); } } } ~~~ 輸出為: ~~~ Creating First Creating Second In body Creating Third Creating SecondExcept Closing Second Closing First Caught: CE ~~~ 請注意,第 3 個對象永遠不會被清除。那是因為它不是在資源規范頭中創建的,所以它沒有被保護。這很重要,因為 Java 在這里沒有以警告或錯誤的形式提供指導,因此像這樣的錯誤很容易漏掉。實際上,如果依賴某些集成開發環境來自動重寫代碼,以使用 try-with-resources 特性,那么它們(在撰寫本文時)通常只會保護它們遇到的第一個對象,而忽略其余的對象。 最后,讓我們看一下拋出異常的 close() 方法: ~~~ // exceptions/CloseExceptions.java class CloseException extends Exception {} class Reporter2 implements AutoCloseable { String name = getClass().getSimpleName(); Reporter2() { System.out.println("Creating " + name); } public void close() throws CloseException { System.out.println("Closing " + name); } } class Closer extends Reporter2 { @Override public void close() throws CloseException { super.close(); throw new CloseException(); } } public class CloseExceptions { public static void main(String[] args) { try( First f = new First(); Closer c = new Closer(); Second s = new Second() ) { System.out.println("In body"); } catch(CloseException e) { System.out.println("Caught: " + e); } } } ~~~ 輸出為: ~~~ Creating First Creating Closer Creating Second In body Closing Second Closing Closer Closing First Caught: CloseException ~~~ 從技術上講,我們并沒有被迫在這里提供一個 catch 子句;你可以通過**main() throws CloseException**的方式來報告異常。但 catch 子句是放置錯誤處理代碼的典型位置。 請注意,因為所有三個對象都已創建,所以它們都以相反的順序關閉 - 即使 Closer.close() 拋出異常也是如此。仔細想想,這就是你想要的結果。但如果你必須親手編寫所有的邏輯,或許會丟失一些東西并使得邏輯出錯。想想那些程序員沒有考慮 Clean up 的所有影響并且出錯的代碼。因此,如果可以,你應當始終使用 try-with-resources。這個特性有助于生成更簡潔,更易于理解的代碼。
                  <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>

                              哎呀哎呀视频在线观看