在你學習在程序中處理異常之前,看一看如果你不處理它們會有什么情況發生是很有好處的。下面的小程序包括一個故意導致被零除錯誤的表達式。
class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
當Java運行時系統檢查到被零除的情況,它構造一個新的異常對象然后拋出該異常。這導致Exc0的執行停止,因為一旦一個異常被拋出,它必須被一個異常處理程序捕獲並且被立即處理。該例中,我們沒有提供任何我們自己的異常處理程序,所以異常被Java運行時系統的默認處理程序捕獲。任何不是被你程序捕獲的異常最終都會被該默認處理程序處理。默認處理程序顯示一個描述異常的字符串,打印異常發生處的堆棧軌跡並且終止程序。
下面是由標准javaJDK運行時解釋器執行該程序所產生的輸出:
java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
注意,類名Exc0,方法名main,文件名Exc0.java和行數4是怎樣被包括在一個簡單的堆棧使用軌跡中的。還有,注意拋出的異常類型是Exception的一個名為ArithmeticException的子類,該子類更明確的描述了何種類型的錯誤方法。本章后面部分將討論,Java提供多個內置的與可能產生的不同種類運行時錯誤相匹配的異常類型。
堆棧軌跡將顯示導致錯誤產生的方法調用序列。例如,下面是前面程序的另一個版本,它介紹了相同的錯誤,但是錯誤是在main( )方法之外的另一個方法中產生的:
class Exc1 {
static void subroutine() {
int d = 0;
int a = 10 / d;
}
public static void main(String args[]) {
Exc1.subroutine();
}
}
默認異常處理器的堆棧軌跡結果表明了整個調用棧是怎樣顯示的:
java.lang.ArithmeticException: / by zero
at Exc1.subroutine(Exc1.java:4)
at Exc1.main(Exc1.java:7)
如你所見,棧底是main的第7行,該行調用了subroutine( )方法。該方法在第4行導致了異常。調用堆棧對於調試來說是很重要的,因為它查明了導致錯誤的精確的步驟。