1. 程式人生 > 其它 >Go程式設計之結構體和介面

Go程式設計之結構體和介面

概念

什麼是異常?

程式在執行期發生的不正常的事件,它會打斷指令的正常執行流程

異常的作用?

增強程式的健壯性。

Java語言使用異常處理機制為程式提供了異常處理能力

Java語言中異常是以什麼形式存在的呢?

異常在java中以類的形式存在,每一個異常類都可以建立異常物件

異常的分類

Java程式執行過程中所發生的異常事件從嚴重性可分為兩類:

  1. 錯誤(Error)

    JVM系統內部錯誤或資源耗盡等嚴重情況-屬於JVM需要負擔的責任,這一類異常事件無法恢復或不可能捕獲,將導致應用程式中斷。

  2. 異常(Exception)

    其它因程式設計錯誤或偶然的外在因素導致的一般性問題。這類異常得到恰當的處理時,程式有機會恢復至正常執行狀況

    1. 非受檢(unchecked)異常(執行時異常 RuntimeException)

      編譯器不要求強制處置的異常。一般是指程式設計時的邏輯錯誤。是程式設計師應該積極避免其出現的異常

      java.lang.RuntimeException及它的子類都是非受檢異常:

      1. 錯誤的型別轉換:java.lang.ClassCastException

      2. 陣列下標越界:java.lang.ArrayIndexOutOfBoundsException

      3. 空指標訪問:java.lang.NullPointerException

      4. 算術異常(除0溢位):java.lang.ArithmeticException

    2. 受檢(checked)異常 --- 一般性異常(編譯時異常 所有Exception直接子類)

      編譯器要求必須處置的異常。指的是程式在執行時由於外界因素造成的一般性異常。

      由於外界因素造成的一般性異常:

      1. 沒有找到指定名稱的類:java.lang.ClassNotFoundException

      2. 訪問不存在的檔案:java.io.FileNotFoundException

      3. 操作檔案時發生的異常:java.io.IOException

      4. 操作資料庫時發生的異常:java.sql.SQLException

異常的處理機制

  1. Java程式在執行過程中如果出現異常,會自動生成一個異常類物件,該異常物件將被自動提交給JVM,這個過程稱為丟擲(throw

    )異常

  2. 當JVM接收到異常物件時,會尋找能處理這一異常的程式碼並把當前異常物件交給其處理,這一過程稱為捕獲(catch)異常和處理異常

  3. 如果JVM找不到可以捕獲異常的程式碼,則執行時系統將終止,相應的Java程式也將退出。

註解:所有異常都是發生在執行階段的。

異常的處理方式

  1. 捕獲異常

    使用try...catch語句進行異常的捕捉

    1 try{
    2     ......  //可能產生異常的程式碼 
    3 }catch( ExceptionName1 e ){
    4     ......  //異常的處理程式碼 
    5 }catch( ExceptionName2 e ){
    6     ......   //異常的處理程式碼 
    7 } finally{
    8     ......   //無論如何都會執行的語句 
    9 }

    註解:

    1. try 程式碼段包含的是可能產生異常的程式碼

    2. 1) try 程式碼段後跟一個或多個catch程式碼段。(或跟一個finally程式碼段)

    3. 當異常發生時,程式會中止當前的流程去執行相應的catch程式碼段

    4. 寫catch程式碼時,先捕獲的異常的範圍不能大於後捕獲的異常的範圍。大的異常要寫在後面

      例如:

      1 try{
      2      //...可能會報異常的程式碼
      3     }catch(ClassNotFoundException e){//小的異常
      4         e.printStackTrach();//catch括號裡面可以是具體的型別異常,也可以是該異常型別的父型別異常
      5     }catch(Exception e){//大的異常
      6         e.printStackTrach();
      7     }
    5. finally段的程式碼無論是否發生異常都執行

    6. 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     }
  2. 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   }
  3. throw丟擲單個具體異常物件(一般手動拋異常)

    1 //異常不僅僅虛擬機器可以拋,我們自己也可以拋。我們可以在程式碼中使用throw關鍵字(注意不帶s)來丟擲某個具體的異常物件。很多情況下我們會手動丟擲執行時異常
    2 throw new RuntimeException("程式出現了異常");
    3 //常常和自定義異常結合
  4. throw和throws區別

    1. throws用來宣告一個方法可能會產生的異常或者異常型別,在方法體內不做任何處理,將異常往呼叫方拋

      1. 在方法聲明後,跟上異常型別名,可以跟多個,異常名之間逗號隔開

      2. throws丟擲的異常是一種可能性,不一定會發生

      3. throws丟擲的可以是一個異常範圍,也可以是具體的異常

    2. throw用來丟擲單個具體異常物件

      1. 用在方法體內,跟的是異常物件名

      2. 只能丟擲一個異常物件

      3. 丟擲的異常在方法體內處理

      4. throw若是丟擲了異常,則說明一定發生了

異常物件的常用方法

異常物件有兩個非常重要的方法:

  1. 獲取異常簡單的描述資訊:

    String msg = exception.getMessage();

  2. 列印異常追蹤的堆疊資訊:

    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的。)。

重寫之後的方法不能比重寫之前的方法丟擲更多(更寬泛)的異常,可以更少。(爭對編譯時異常)

finally

出現異常時,finally塊裡的程式碼會執行,但是當退出JVM時,finally語句塊也不會執行

例如:

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語句中的規則:

  1. 方法體中的程式碼必須遵循自上而下順序依次逐行執行(亙古不變的語法!)

  2. return語句一旦執行,整個方法必須結束(亙古不變的語法!)

底層這兩條規則都遵循了