Go程式設計之結構體和介面
程式在執行期發生的不正常的事件,它會打斷指令的正常執行流程
異常的作用?
增強程式的健壯性。
Java語言使用異常處理機制為程式提供了異常處理能力
Java語言中異常是以什麼形式存在的呢?
-
錯誤(Error)
JVM系統內部錯誤或資源耗盡等嚴重情況-屬於JVM需要負擔的責任,這一類異常事件無法恢復或不可能捕獲,將導致應用程式中斷。
-
異常(Exception)
其它因程式設計錯誤或偶然的外在因素導致的一般性問題。這類異常得到恰當的處理時,程式有機會恢復至正常執行狀況
-
非受檢(unchecked)異常(執行時異常 RuntimeException)
編譯器不要求強制處置的異常。一般是指程式設計時的邏輯錯誤。是程式設計師應該積極避免其出現的異常
java.lang.RuntimeException及它的子類都是非受檢異常:
-
錯誤的型別轉換:java.lang.ClassCastException
-
陣列下標越界:java.lang.ArrayIndexOutOfBoundsException
-
空指標訪問:java.lang.NullPointerException
-
算術異常(除0溢位):java.lang.ArithmeticException
-
-
受檢(checked)異常 --- 一般性異常(編譯時異常 所有Exception直接子類)
編譯器要求必須處置的異常。指的是程式在執行時由於外界因素造成的一般性異常。
由於外界因素造成的一般性異常:
-
沒有找到指定名稱的類:java.lang.ClassNotFoundException
-
訪問不存在的檔案:java.io.FileNotFoundException
-
操作檔案時發生的異常:java.io.IOException
-
-
-
異常的處理機制
-
Java程式在執行過程中如果出現異常,會自動生成一個異常類物件,該異常物件將被自動提交給JVM,這個過程稱為丟擲(throw
-
當JVM接收到異常物件時,會尋找能處理這一異常的程式碼並把當前異常物件交給其處理,這一過程稱為捕獲(catch)異常和處理異常
-
如果JVM找不到可以捕獲異常的程式碼,則執行時系統將終止,相應的Java程式也將退出。
註解:所有異常都是發生在執行階段的。
-
使用try...catch語句進行異常的捕捉
1 try{ 2 ...... //可能產生異常的程式碼 3 }catch( ExceptionName1 e ){ 4 ...... //異常的處理程式碼 5 }catch( ExceptionName2 e ){ 6 ...... //異常的處理程式碼 7 } finally{ 8 ...... //無論如何都會執行的語句 9 }
註解:
-
try 程式碼段包含的是可能產生異常的程式碼
-
1) try 程式碼段後跟一個或多個catch程式碼段。(或跟一個finally程式碼段)
-
當異常發生時,程式會中止當前的流程去執行相應的catch程式碼段
-
寫catch程式碼時,先捕獲的異常的範圍不能大於後捕獲的異常的範圍。大的異常要寫在後面
例如:
1 try{ 2 //...可能會報異常的程式碼 3 }catch(ClassNotFoundException e){//小的異常 4 e.printStackTrach();//catch括號裡面可以是具體的型別異常,也可以是該異常型別的父型別異常 5 }catch(Exception e){//大的異常 6 e.printStackTrach(); 7 }
-
finally段的程式碼無論是否發生異常都執行
-
java 8新特性:一個catch程式碼可以可以宣告多個能處理的特定異常的型別,多個型別之間用”|”隔開
例如:catch( ExceptionName1 | ExceptionName2 e){
...... //異常的處理程式碼
}
1 public static void main(String[] args){ 2 try { 3 method(); 4 } catch (ClassNotFoundException | FileNotFoundException e) { 5 e.printStackTrace(); 6 } 7 //這就是try...catch語句捕捉異常 8 } 9 public static void method() throws ClassNotFoundException,FileNotFoundException { 10 System.out.println("我是方法"); 11 }
-
-
throws丟擲異常型別(類似於推卸責任)
在方法的位置上,使用throws關鍵字丟擲異常,拋給上一級,誰呼叫就拋給誰,如果異常不處理繼續往上拋,最終拋給main()方法,main()方法繼續往上拋,拋給了JVM,JVM只有一個結果,使java程式終止
例如:
1 public static void main(String[] args) throws FileNotFoundException{ 2 m1();//最終拋給了JVM JVM終止程式 3 //一般main方法中的異常建議使用try..catch進行捕捉。 4 } 5 private static void m1() throws FileNotFoundException{ 6 m2();//throws 後面可以有多個異常 使用 “,” 隔開 7 } 8 private static void m2() throws FileNotFoundException{ 9 m3();//呼叫者可以拋被呼叫者異常的父類或者就拋被呼叫者異常,其他不行 10 } 11 12 private static void m3() throws FileNotFoundException{ 13 new FileInputStream("D:\\aaa.txt"); 14 System.out.println("以上程式碼出異常,這裡不會執行"); 15 }
-
throw丟擲單個具體異常物件(一般手動拋異常)
1 //異常不僅僅虛擬機器可以拋,我們自己也可以拋。我們可以在程式碼中使用throw關鍵字(注意不帶s)來丟擲某個具體的異常物件。很多情況下我們會手動丟擲執行時異常 2 throw new RuntimeException("程式出現了異常"); 3 //常常和自定義異常結合
-
throw和throws區別
-
throws用來宣告一個方法可能會產生的異常或者異常型別,在方法體內不做任何處理,將異常往呼叫方拋
-
在方法聲明後,跟上異常型別名,可以跟多個,異常名之間逗號隔開
-
throws丟擲的異常是一種可能性,不一定會發生
-
throws丟擲的可以是一個異常範圍,也可以是具體的異常
-
-
throw用來丟擲單個具體異常物件
-
用在方法體內,跟的是異常物件名
-
只能丟擲一個異常物件
-
丟擲的異常在方法體內處理
-
-
-
-
獲取異常簡單的描述資訊:
String msg = exception.getMessage();
-
列印異常追蹤的堆疊資訊:
exception.printStackTrace();
例如:
1 public static void main(String[] args) { 2 //new一個異常 3 NullPointerException e = new NullPointerException("空指標異常"); 4 //new了一個異常 但是沒丟擲 所以下面的程式碼繼續執行 不會中斷程式 5 String msg = e.getMessage();//獲取異常的資訊 6 System.out.println(msg);//列印的就是 空指標異常 7 e.printStackTrace();//列印異常堆疊資訊 底層有一個專門的執行緒負責這個事情的 8 //java後臺列印異常堆疊追蹤資訊的時候,採用了非同步執行緒的方式列印的。 9 }
注意:以後檢視異常的追蹤資訊,從上往下一行一行看,但是需要注意的是:SUN寫的程式碼就不用看了(看包名就知道是自己的還是SUN的。)。
例如:
1 public static void main(String[] args){ 2 try{ 3 System.out.println("try..."); 4 System.exit(); 5 }finally{ 6 System.out.println("finally..."); 7 } 8 }
finally面試題
1 public static void main(String[] args) { 2 int result = m(); 3 System.out.println(result); //返回的是100 4 } 5 6 public static int m(){ 7 int i = 100; 8 try { 9 // 這行程式碼出現在int i = 100;的下面,所以最終結果必須是返回100 10 // return語句還必須保證是最後執行的。一旦執行,整個方法結束。 11 return i; 12 } finally { 13 i++;//這行程式碼執行了 14 } 15 } 16 17 //反編譯底層原始碼 18 public static int m(){ 19 int i = 100; 20 int j = i; 21 i++; 22 return j; 23 } 24 /** 25 JVM規範裡面明確說明了這種情況: 26 大意就是如果在try中return的情況下,先把try中將要return的值先存到一個本地變數中,即本例中的i=100將會被儲存下來。接下來去執行finally語句,最後返回的是存在本地變數中的值,即返i=100. 27 28 還有一點要注意的,如果你在finally裡也用了return語句,比如return ++i。那麼程式返回值會是101。因為規範規定了,當try和finally裡都有return時,會忽略try的return,而使用finally的return。 29 */ 30 //總結:1、try中有return, 會先將值暫存,無論finally語句中對該值做什麼處理,最終返回的都是try語句中的暫存值。 2、當try與finally語句中均有return語句,會忽略try中return。
Java語句中的規則:
-
方法體中的程式碼必須遵循自上而下順序依次逐行執行(亙古不變的語法!)
-
return語句一旦執行,整個方法必須結束(亙古不變的語法!)