<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國際加速解決方案。 廣告
                轉:http://www.importnew.com/26613.html [TOC] ## 1.簡介 程序運行時,發生的不被期望的事件,它阻止了程序按照程序員的預期正常執行,這就是異常。異常發生時,是任程序自生自滅,立刻退出終止,還是輸出錯誤給用戶?或者用C語言風格:用函數返回值作為執行狀態?。 **Java提供了更加優秀的解決辦法:異常處理機制。** 異常處理機制能讓程序在異常發生時,按照代碼的預先設定的異常處理邏輯,針對性地處理異常,讓程序盡最大可能恢復正常并繼續執行,且保持代碼的清晰。 Java中的異常可以是函數中的語句執行時引發的,也可以是程序員通過throw 語句手動拋出的,只要在Java程序中產生了異常,就會用一個對應類型的異常對象來封裝異常,JRE就會試圖尋找異常處理程序來處理異常。 **Throwable類是Java異常類型的頂層父類**,一個對象只有是 Throwable 類的(直接或者間接)實例,他才是一個異常對象,才能被異常處理機制識別。JDK中內建了一些常用的異常類,我們也可以自定義異常。 ## 2.Java異常的分類和類結構圖 > Java標準庫內建了一些通用的異常,這些類以Throwable為頂層父類。**Throwable又派生出Error類和Exception類**。 ![](https://box.kancloud.cn/332cd9cd2fa8113c7fe83d0540ca2a30_718x458.png) ### 2.1 錯誤 Error類以及他的子類的實例,代表了JVM本身的錯誤。錯誤不能被程序員通過代碼處理,Error很少出現。因此,程序員應該關注Exception為父類的分支下的各種異常類。 ### 2.2 異常 Exception以及他的子類,代表程序運行時發送的各種不期望發生的事件。可以被Java異常處理機制使用,是異常處理的核心。 ### 2.2.1 異常分類 > ****總體上我們根據Javac對異常的處理要求,將異常類分為2類。**** * [ ] **1. 非檢查異常(unckecked exception):** * **Error 和 RuntimeException 以及他們的子類。** * javac在編譯時,不會提示和發現這樣的異常,不要求在程序處理這些異常。所以如果愿意,我們可以編寫代碼處理(使用try…catch…finally)這樣的異常,也可以不處理。 * **對于這些異常,我們應該修正代碼,而不是去通過異常處理器處理 。** * 這樣的異常發生的原因多半是代碼寫的有問題。如除0錯誤ArithmeticException,錯誤的強制類型轉換錯誤ClassCastException,數組索引越界ArrayIndexOutOfBoundsException,使用了空對象NullPointerException等等。 * [ ] **2. 檢查異常(checked exception):** * 除了Error 和 RuntimeException的其它異常,javac強制要求程序員為這樣的異常做預備處理工作(使用try…catch…finally或者throws,IDE編寫代碼時,報出的異常都是檢查異常)。 * 在方法中要么用try-catch語句捕獲它并處理,要么用throws子句聲明拋出它,否則編譯不會通過。這樣的異常一般是由程序的運行環境導致的。因為程序可能被運行在各種未知的環境下,而程序員無法干預用戶如何使用他編寫的程序,于是程序員就應該為這樣的異常時刻準備著。如SQLException , IOException,ClassNotFoundException 等。 * 需要明確的是:檢查和非檢查是對于javac來說的,這樣就很好理解和區分了 ## 3.初識異常 下面的代碼會演示2個異常類型:ArithmeticException 和 InputMismatchException。前者由于整數除0引發,后者是輸入的數據不能被轉換為int類型引發。 ``` package com.example; import java. util .Scanner ; public class AllDemo { public static void main (String [] args ) { System . out. println( "----歡迎使用命令行除法計算器----" ) ; CMDCalculate (); } public static void CMDCalculate () { Scanner scan = new Scanner ( System. in ); int num1 = scan .nextInt () ; int num2 = scan .nextInt () ; int result = devide (num1 , num2 ) ; System . out. println( "result:" + result) ; scan .close () ; } public static int devide (int num1, int num2 ){ return num1 / num2 ; } } ``` ``` /***************************************** ----歡迎使用命令行除法計算器---- 0 Exception in thread "main" java.lang.ArithmeticException : / by zero at com.example.AllDemo.devide( AllDemo.java:30 ) at com.example.AllDemo.CMDCalculate( AllDemo.java:22 ) at com.example.AllDemo.main( AllDemo.java:12 ) ----歡迎使用命令行除法計算器---- r Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor( Scanner.java:864 ) at java.util.Scanner.next( Scanner.java:1485 ) at java.util.Scanner.nextInt( Scanner.java:2117 ) at java.util.Scanner.nextInt( Scanner.java:2076 ) at com.example.AllDemo.CMDCalculate( AllDemo.java:20 ) at com.example.AllDemo.main( AllDemo.java:12 ) *****************************************/ ``` **異常是在執行某個函數時引發的,而函數又是層級調用,形成調用棧的,因為,只要一個函數發生了異常,那么他的所有的caller都會被異常影響。當這些被影響的函數以異常信息輸出時,就形成的了異常追蹤棧。** **異常最先發生的地方,叫做異常拋出點。** **最上邊的異常就是異常拋出點(棧:先進后出)** ![](https://box.kancloud.cn/2a8ca6e8dbd11f39562e82514a10e17c_845x209.png) 從上面的例子可以看出,當devide函數發生除0異常時,devide函數將拋出ArithmeticException異常,因此調用他的CMDCalculate函數也無法正常完成,因此也發送異常,而CMDCalculate的caller——main 因為CMDCalculate拋出異常,也發生了異常,這樣一直向調用棧的棧底回溯。**這種行為叫做異常的冒泡,異常的冒泡是為了在當前發生異常的函數或者這個函數的caller中找到最近的異常處理程序。**由于這個例子中沒有使用任何異常處理機制,因此異常最終由main函數拋給JRE,導致程序終止。 代碼中我選擇使用throws聲明異常,讓函數的調用者去處理可能發生的異常。但是為什么只throws了IOException呢?因為FileNotFoundException是IOException的子類,在處理范圍內。 ``` @Test public void testException() throws IOException { //FileInputStream的構造函數會拋出FileNotFoundException FileInputStream fileIn = new FileInputStream("E:\\a.txt"); int word; //read方法會拋出IOException while((word = fileIn.read())!=-1) { System.out.print((char)word); } //close方法會拋出IOException fileIn.clos } ``` ## 4.異常處理的基本語法 > 在編寫代碼處理異常時,對于檢查異常,有2種不同的處理方式:使用try…catch…finally語句塊處理它。或者,在函數簽名中使用throws 聲明交給函數調用者caller去解決。 ### 4.1 try…catch…finally語句塊 ``` try{ //try塊中放可能發生異常的代碼。 //如果執行完try且不發生異常,則接著去執行finally塊和finally后面的代碼(如果有的話)。 //如果發生異常,則嘗試去匹配catch塊。 }catch(SQLException SQLexception){ //每一個catch塊用于捕獲并處理一個特定的異常,或者這異常類型的子類。Java7中可以將多個異常聲明在一個catch中。 //catch后面的括號定義了異常類型和異常參數。如果異常與之匹配且是最先匹配到的,則虛擬機將使用這個catch塊來處理異常。 //在catch塊中可以使用這個塊的異常參數來獲取異常的相關信息。異常參數是這個catch塊中的局部變量,其它塊不能訪問。 //如果當前try塊中發生的異常在后續的所有catch中都沒捕獲到,則先去執行finally,然后到這個函數的外部caller中去匹配異常處理器。 //如果try中沒有發生異常,則所有的catch塊將被忽略。 }catch(Exception exception){ //... }finally{ //finally塊通常是可選的。 //無論異常是否發生,異常是否匹配被處理,finally都會執行。 //一個try至少要有一個catch塊,否則, 至少要有1個finally塊。但是finally不是用來處理異常的,finally不會捕獲異常。 ** //finally主要做一些清理工作,如流的關閉,數據庫連接的關閉等。 ** } ``` 1.try塊中的局部變量和catch塊中的局部變量(包括異常變量),以及finally中的局部變量,他們之間不可共享使用。 2.每一個catch塊用于處理一個異常。異常匹配是按照catch塊的順序從上往下尋找的,只有第一個匹配的catch會得到執行。 **匹配時,不僅運行精確匹配,也支持父類匹配,** 因此,如果同一個try塊下的多個catch異常類型有父子關系,應該將子類異常放在前面,父類異常放在后面,這樣保證每個catch塊都有存在的意義。 3.java中,異常處理的任務就是將**執行控制流***從異常發生的地方轉移到能夠處理這種異常的地方去*。也就是說:當一個函數的某條語句發生異常時,這條語句的后面的語句不會再執行,它失去了焦點。**執行流跳轉到最近的匹配的異常處理catch代碼塊去執行,異常被處理完后,執行流會接著在“處理了這個異常的catch代碼塊”后面接著執行。** > 1.有的編程語言當異常被處理后,控制流會恢復到異常拋出點接著執行,這種策略叫做:resumption model of exception handling(恢復式異常處理模式 ) > 2.而Java則是讓執行流恢復到處理了異常的catch塊后接著執行,這種策略叫做:termination model of exception handling(終結式異常處理模式) ``` public static void main(String[] args){ try { foo(); }catch(ArithmeticException ae) { System.out.println("處理異常"); } } public static void foo(){ int a = 5/0; //異常拋出點 System.out.println("為什么還不給我漲工資!!!"); //////////////////////不會執行 } ```
                  <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>

                              哎呀哎呀视频在线观看