歡迎您光臨本站 註冊首頁

JAVA基礎--如何通過異常處理錯誤

←手機掃碼閱讀     bom485332 @ 2020-06-11 , reply:0

《Thinking in Java》上對這章的講解不少,可見重要性,學習和總結一些主要的記錄下來。

一、創建自定義異常

  package Exception;    class SimpleException extends Exception{}      public class InheritingException{        public void f() throws SimpleException {     System.out.println("Throw SimpleException from f()");     throw new SimpleException();    }        public static void main(String[] args) {     InheritingException sed = new InheritingException();     try {      sed.f();     } catch (SimpleException e) {      e.printStackTrace();     }    }       }

 

輸出:

Throw SimpleException from f()
 Exception.SimpleException
 at Exception.InheritingException.f(InheritingException.java:10)
 at Exception.InheritingException.main(InheritingException.java:19)

  throw與throws的區別與詳情

  編譯器創建了默認構造器,它將自動調用基類的默認構造器。

  對異常來說,最重要的部分就是類名,其它也沒用,可以增加一個帶參的構造方法。

  比如NullPointerException:

   public class NullPointerException extends RuntimeException {    private static final long serialVersionUID = 5162710183389028792L;       /**    * Constructs a {@code NullPointerException} with no detail message.    */    public NullPointerException() {     super();   }      /**    * Constructs a {@code NullPointerException} with the specified     * detail message.    *    * @param s the detail message.    */    public NullPointerException(String s) {     super(s);    }   }

 

二、捕獲異常

  1)try塊

    如果在方法內部拋出了異常(或者在方法內部調用的其他方法拋出了異常),這個方法將在拋出異常的過程中結束。

    要是不希望方法就此結束,可以在方法內設置一個特殊的塊來捕獲異常。

  try{   //exceptions   }

 

   2)異常處理程序

    異常處理程序緊跟在try塊之後,以關鍵字catch表示:

  try{   //exceptions   } catch(Type1 id1) {   //Type1   } catch(Type2 id2) {   //Type2  }

 

    當異常被拋出時,異常處理機制將負責搜尋參數與異常類型相匹配的第一個處理程序。然後進入catch子句執行,此時認為異常得到了處理。

    注意,只有匹配的catch子句才能得到執行,這與switch語句不同。

   3)棧軌跡

    printStackTrace()方法所提供的信息可以通過getStackTrace()方法來直接訪問,這個方法將返回一個由棧軌跡中的元素所構成的數組,其中每一個元素都表示

  棧中的一幀。元素0是棧頂元素,並且是調用序列中的最後一個方法調用。數組中最後一個元素和棧底是調用序列中的第一個方法調用。

   public class WhoCalled {    static void f() {     try {      throw new Exception();     } catch (Exception e) {      for(StackTraceElement ste : e.getStackTrace()) {       System.out.println("line: " + ste.getLineNumber() + " method: " + ste.getMethodName());      }     }    }    static void g() {f();}    static void h() {g();}    public static void main(String[] args) {f();g();h();}   }

 

  程序輸出:

line: 5 method: f
 line: 14 method: main
 line: 5 method: f
 line: 12 method: g
 line: 14 method: main
 line: 5 method: f
 line: 12 method: g
 line: 13 method: h
 line: 14 method: main

三、Java標準異常

  Throwable這個Java類被用來表示任何可以作為異常被拋出的類。

  Throwable對象可分為兩種類型:

1  Error用來表示編譯時和系統錯誤。

2  Exception是可以被拋出的基本類型,程序員關心的基類型通常是Exception。

四、RuntimeException

  if(t == null) {   throw new NullPointerException();   }

 

  如果對Null引用進行調用,Java會自動拋出NullPointerException異常,所以上述代碼是多餘的,它屬於Java的標準運行時檢測的一部分:

  public class NeverCaught {    static void f() {     throw new RuntimeException();    }    static void g() {f();}    public static void main(String[] args) {     g();    }   }

 

輸出:

Exception in thread "main" java.lang.RuntimeException

at Exception.NeverCaught.f(NeverCaught.java:6)

at Exception.NeverCaught.g(NeverCaught.java:10)

at Exception.NeverCaught.main(NeverCaught.java:14)

  從輸出可以發現,RuntimeException是一個特例,對於這種異常類型,編譯器不需要異常說明,其輸出被報告給了System.err。

  如果RuntimeException沒有被捕獲而直達main(),那麼在程序退出前將調用異常的printStackTrace()方法。

  *注意:

    只能在代碼中忽略RuntimeException(及其子類)類型的異常,其它異常類型的處理都是由編譯器強制實施的。

  1)常見的五種RuntimeException

NullPointerException - 空指針引用異常

ClassCastException - 類型強制轉換異常

IllegalArgumentException - 傳遞非法參數異常

ArithmeticException - 算術運算異常

ArrayStoreException - 向數組中存放與聲明類型不兼容對象異常

IndexOutOfBoundsException - 下標越界異常

NegativeArraySizeException - 創建一個大小為負數的數組錯誤異常

NumberFormatException - 數字格式異常

SecurityException - 安全異常

UnsupportedOperationException - 不支持的操作異常

五、使用finally進行清理

   class ThreeException extends Exception {}   public class FinallyWorks {    static int count = 0;    public static void main(String[] args) {     while(true) {      try {       if(count++ == 0) {        throw new ThreeException();       }       System.out.println("No exception");      } catch (ThreeException e) {       System.out.println("ThreeException");      } finally {       System.out.println("In finally clause");       if(count == 2)         break;      }     }    }   }

 

  這個程序給了我們一些思路(確實。。),如果把try塊放在循環裡,就建立了一個“程序繼續執行之前必須要到達”的條件。

  還可以加入一個static類型的計數器或者別的裝置,使循環在放棄之前能夠嘗試一定的次數。這將使程序的健壯性更上一個臺階(好叼的樣子)。

  1)finally用來做什麼

    當要把除內存之外的資源恢復到它們的初始狀態時,就要用到finally子句。

  2)在return中使用finally

    因為finally子句總是會執行的,所以在一個方法中,可以從多個點返回,並且可以保證重要的清理工作仍舊會執行:

  class ThreeException extends Exception {}   public class FinallyWorks {    static int count = 0;    public static void main(String[] args) {     while(true) {      try {       if(count++ == 0) {        throw new ThreeException();       }       System.out.println("No exception");       return;      } catch (ThreeException e) {       System.out.println("ThreeException");      } finally {       System.out.println("In finally clause");       if(count == 3)         break;      }     }    }   }

 

第一次循環,首先執行第7行,符合條件,拋出異常,執行catch塊,最後執行finally清理,不符合第16行判斷,繼續循環

第二次循環,不符合第7行判斷,拋出異常,並return,但依舊執行finally清理,不符合第16行判斷,但try塊中已經執行return,所以程序結束,輸出:

ThreeException
 In finally clause
 No exception
 In finally clause

  3)Java異常的缺憾:異常丟失

   public class ExceptionSilencer {    public static void main(String[] args) {    try {      throw new RuntimeException();     } finally {      return;     }    }   }



[bom485332 ] JAVA基礎--如何通過異常處理錯誤已經有239次圍觀

http://coctec.com/docs/java/show-post-238072.html