天天看點

JAVA棧異常_Java中的異常棧軌迹和異常鍊

Java中允許對異常進行再次抛出,以送出給上一層進行處理,最為明顯的例子為Java的正常異常。

正常異常:有Java所定義的異常,不需要異常聲明,在未被try-catch的情況下,會被預設上報到main()方法。

Example:

public class TestException {

TestException(int i) throws ExceptionA,ExceptionB{

int a[]={0,}; a[1]=1;

}

}

當從main()方法中調用TestException類的構造函數的時候,會得到以下的異常提示,從中可以看出異常的冒泡機制(這是一個棧資訊)。

JAVA棧異常_Java中的異常棧軌迹和異常鍊

異常的冒泡上傳機制:當一個異常對象産生了以後,其會按照調用層次(一般是方法的調用層次)進行冒泡,直到被try-catch處理,或上報至main()方法,有編譯器進行提示。

Example:

JAVA棧異常_Java中的異常棧軌迹和異常鍊

firstThrow()提示錯誤的原因為, firstThrow()的函數聲明中包括了MyException的異常聲明,而secondThrow()中調用了firstThrow()卻未對可能抛出的異常對象提供任何處理方案,這是編譯器所不能允許發生的事情。(這也是為了保證底層異常對象在冒泡過程中,能得到合适的處理和重視!)

注意此截圖中,MyEclipse提供了兩種方式幫助fix這個程式,這兩種方式常用的異常應對手段:

1、本方法不給予處理,将異常上報給上一層。

1 public classTestExceptionChain {2 void firstThrow() throwsMyException3 {4 print("Oringinally creat a MyException and throw it out");5 throw newMyException();6

7 }8 void secondThrow() throwsMyException9 {10 firstThrow();11 }12 TestExceptionChain() throwsMyException{13 secondThrow();14 }15 }

1 public static voidmain(String[] args) {2 try{3

4 TestExceptionChain testExceptionChain=newTestExceptionChain();5 }6 catch(MyException e)7 {8 e.printStackTrace();9 print("Catch a my exception!");10 }11

12 }

控制台的輸出為:

JAVA棧異常_Java中的異常棧軌迹和異常鍊

從異常棧的記錄資訊可以發現,與代碼相對應的異常抛出機制和次序:

firstThrow()産生MyException對象->異常冒泡至調用其的secondThrow()->異常冒泡至調用secondThrow()的TestExceptionChain的構造方法->冒泡至printtry的main()方法。

注意到:異常對象一直被抛出,直至在printtry的mian()方法中被try-catch捕獲!

2、try-catch方式,捕捉上報的異常,而後進行相應處理或抛出另一異常。

2、1捕獲異常後,進行相應處理。

Example:

1 public classTestExceptionChain {2 void firstThrow() throwsMyException3 {4 print("Oringinally creat a MyException and throw it out");5 throw newMyException();6 }7 voidsecondThrow()8 {9 try

10 {11 firstThrow();12 }13 catch(MyException e)14 {15 print("I have just caught a MyExcepton,but i want to do nothing for it");16 e.printStackTrace();17 }18 }19 TestExceptionChain(){20 secondThrow();21 }

JAVA棧異常_Java中的異常棧軌迹和異常鍊

從圖中可以發現,異常在secondThrow() 中被try-catch子產品捕獲,并執行了相應的處理操作,是以其函數聲明中無需添加異常聲明,異常不會被上報。

故mian()方法被改寫成了以下的代碼:

1 TestExceptionChain testExceptionChain=new TestExceptionChain();

注意此處異常棧的資訊,表示的是異常産生的層次資訊,并非異常資訊的上報層次,因為其已經在secondThorow()中被捕獲處理。

2.2 捕獲異常後,抛出另一個異常。

Example:

1 public classTestExceptionChain {2 void firstThrow() throwsMyException3 {4 print("Oringinally creat a MyException and throw it out");5 throw newMyException();6 }7 void secondThrow() throwsYouException8 {9 try

10 {11 firstThrow();12 }13 catch(MyException e)14 {15 print("I have just caught a MyExcepton,but i want to create a YouException and throw it out");16 e.printStackTrace();17 throw newYouException();18 }19 }20 TestExceptionChain() throwsYouException{21 secondThrow();22 }23 }24 class MyException extendsException{}25 class YouException extends Exception{}

JAVA棧異常_Java中的異常棧軌迹和異常鍊

從異常棧資訊中可以發現,新抛出的YouException對象是從secondThrow()中開始的。

*Java中還提供了fillInStackTrace()方法,用于對捕獲的異常的棧資訊進行重寫。

Example:

1 try{2

3 TestExceptionChain testExceptionChain=newTestExceptionChain();4 }5 catch(YouException e)6 {7 print("Catch a YouException!");8 e.fillInStackTrace();9 e.printStackTrace();10

11 }

JAVA棧異常_Java中的異常棧軌迹和異常鍊

由于使用了fillInstack()方法,關于YouException的異常資訊被重寫,從其被從寫處重新記錄!