《Java編程思想》之異常處理

來源:互聯網
上載者:User

1、拋出異常之後

1).使用new在對象上建立異常對象

2).終止當前的執行路徑

3).從當前環境中彈出對異常對象的引用

4).異常處理機制接管程式,並開始執行異常處理機制

2、異常處理理論上有兩種基本模型

1).終止模型:一旦異常拋出,就表明錯誤無法挽回,也能回來繼續執行。比較實用。

2).恢複模型:異常處理之後繼續執行程式。但是可能導致“耦合”。

3、自定異常類(具有帶參數的構造器)

class SimpleException extends Exception{   public SimpleException(){}   public SimpleException(String msg){      super(msg);   }}public class SimpleExceptionDemo{   public void func() throws SimpleException{      System.out.println("Throw SimpleExceptionfrom func().");      throw new SimpleException();   }   public void func1() throws SimpleException{      System.out.println("ThrowSimpleException from func1().");      throw new SimpleException("Originated in func1()");   }   public static void main(String[] args){      SimpleExceptionDemo sed = new SimpleExceptionDemo();      try {        sed.func();      } catch (SimpleException e) {        e.printStackTrace();      }      try {        sed.func1();      } catch (SimpleException e) {        e.printStackTrace();      }   }}

運行結果

4、異常說明:實用關鍵字throws,告知用戶端程式員可能會拋出的異常類型。

5、在定義抽象基類和介面時,可以throws一些實際上並不拋出的異常。這樣做的好處:為異常先佔個位子,以後就可以拋出這種異常而不用修改已有的代碼。

6、捕獲所有異常(最好放在處理常式列表的末位):

catch (Exception e) {   System.err.println("Caught an exception");}

7、如果當前異常對象重新拋出,那麼printStackTrace()方法顯示的將是原來異常拋出點的調用棧資訊,而非重新拋出點的資訊。要想更新這個資訊,可以調用fillInStackTrace()方法,這將返回一個Throwable對象,它是通過把當前調用棧資訊填入原來那個異常對象而建立的。

8、

public static void main(String[] args) throws Throwable{      try{        throw new Throwable();      }catch(Exception e){        System.err.println("Caught inmain()");      }   }

因為Throwable是Exception的基類,所以下面程式中將不能再main()裡捕獲。

9、RuntimeException(或任何從它繼承的異常)是一個特例,對於這種異常,編譯器不需要異常說明。原因:

1).無法預料的錯誤。比如在你控制範圍之外傳遞進來的null引用。

2).作為程式員,應該在代碼中進行檢查的錯誤。(比如對於ArrayIndexOutOfBoundsException,就得注意一下數組的大小了。)在一個地方發生的異常,常常會在另一個地方導致錯誤。

10、finally的作用:把除了記憶體之外的資源恢複到它們的初始狀態。例如:已經開啟的檔案盒網路連接,在螢幕上畫的圖形,甚至可以是外部世界的某個開關。

11、異常丟失

class FirstException extends Exception{   public String toString(){      return "The firstException.";   }}class SecondException extends Exception{   public String toString(){      return "The secondException.";   }} public class ErrorFinally{   void firstFunc() throws FirstException{      throw new FirstException();   }   void secondFunc() throws SecondException{      throw new SecondException();   }   public static void main(String[] args) throws Exception{      ErrorFinally error = new ErrorFinally();      try {        error.firstFunc();      } finally{        error.secondFunc();      }   }}

運行結果:

    可以看到,FirstException不見了,它被finally裡的SecondException取代了。

12、異常的限制:當覆蓋方法的時候,只能拋出在基類方法的異常說明裡列出的那些異常。這個限制很有用,因為這意味著,當基類使用的代碼應用到其衍生類別對象的時候,一樣能夠工作(當然,這是物件導向的基本概念),異常也不例外。

1).衍生類別建構函式的異常說明必須包含基類構造器的異常說明。

2).衍生類別構造器不能捕獲基類構造器拋出的異常。(P275第三段最後一句怎麼理解??)

3).衍生類別的方法可以不拋出異常,即使基類的方法有拋出異常。

4).衍生類別的方法可以拋出繼承自"基類方法所拋出異常"的異常。

請看下面例子:

class BaseException extends Exception{}class FuncException extends Exception{}class OtherfuncException extends FuncException{}class Base {   Base() throws BaseException {        }   void func() throws FuncException {      System.out.println("Base.func()");   }   void otherFunc() throws FuncException {      System.out.println("Base.otherFunc()");   }}public class InheritBase extends Base{   //衍生類別建構函式的異常說明必須包含基類構造器的異常說明   public InheritBase() throws BaseException {      super();   }   //衍生類別的方法可以不拋出異常,即使基類的方法有拋出異常。   void func(){      System.out.println("InheritBase.func");   }   //衍生類別的方法可以拋出繼承自"基類方法所拋出異常"的異常,如下OtherfuncException繼承自FuncException   //因為例外處理常式能捕獲FuncException就一定能捕獲OtherfuncException。   void otherFunc() throws OtherfuncException{      System.out.println("InheritBase.otherFunc()");   }   public static void main(String[] args){      try {        Base ib = new InheritBase();        ib.func();      } catch (BaseException e) {        System.err.println("Caught BaseException.");      } catch (FuncException e) {        System.err.println("Caught funcException.");      }   }}

13、把異常傳給控制台

public static void main(String[] args) throws Exception{     }

14、把“被檢查的異常”轉換為“不檢查的異常”:把“被檢查的異常”這種功能給屏蔽掉。

1).

try {       } catch (BeCheckedException e) {   throw new RuntimeException(e);}

這樣做的好處:不用“吐下”異常(“吐下”後異常完全消失),也不必把它放到方法的異常說明裡(throws),而異常鏈還能保證你不會丟失任何原始異常的資訊。

2).你也可以不寫try-catch字句和/或異常說明,直接忽略異常,讓它沿著調用棧往上“冒泡”。同時,還可以用getCause()捕獲並處理特定的異常,如下例子:

class ZeroException extends Exception{}class FirstException extends Exception{}class secondException extends Exception{}class SomeOtherException extends Exception{}//把”被檢查的異常“封裝起來class WrapCheckException{   void throwRuntimeException(int type){      try{        switch(type){           case 0: throw new ZeroException();           case 1: throw new FirstException();           case 2: throw new secondException();           default: return;        }      }catch(Exception e){        throw new RuntimeException(e);      }   }}public class TurnOffChecking{   public static void main(String[] args){      WrapCheckException wce = new WrapCheckException();      wce.throwRuntimeException(3);      for(int i = 0; i < 4; i++){        try{           if(i < 3)              wce.throwRuntimeException(i);           else              throw new SomeOtherException();        }catch(SomeOtherException e){           System.out.println("SomeOtherException:" + e);        }catch(RuntimeException e){           try {              //用getCause捕獲特定異常              throw e.getCause();           } catch (ZeroException e1) {              System.out.println("ZeroException:" + e1);           } catch (FirstException e1) {              System.out.println("FirstException:" + e1);           } catch (secondException e1) {              System.out.println("secondException:" + e1);           } catch (Throwable e1) {              System.out.println("Throwable:" + e1);           }        }      }   }}

運行結果:


1).WrapCheckException. throwRuntimeException()把不同的異常封裝進了RuntimeException對象。

2).可以不用try塊就可以調用throwRuntimeException(),但是,也可以使用try塊捕獲你想捕獲的異常。

3).程式中把getCause()的結果(也就是被封裝的那個原始異常)拋出來,然後用它們自己的catch子句進行處理。

 以上內容整理自《Java編程思想》,若有遺漏,請您不吝指出。

覺得自己進度有點慢,多麼想一口氣把這本書看完。我還有幾本?17天。現在才267頁。我得加速!!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.