當程式發生錯誤而無法處理的時候,會丟出對應的例外物件,除此之外,在某些時刻,您可能會想要自行丟出例外,例如在捕捉例外並處理結束後,再將例外丟出,讓下一層例外處理區塊來捕捉;另一個狀況是重新包裝例外,將捕捉到的例外以您自己定義的例外物件加以包裝丟出。若想要自行丟出例外,您可以使用 "throw" 關鍵字,並生成指定的例外物件,例如:
throw new ArithmeticException();
舉個例子來說明,在 Java 的除法中,允許浮點數運算時除數為 0,所得到的結果是 Infinity,也就是無窮數,如果您想要自行檢驗除零錯誤,可以自行丟出 ArithmeticException 例外,這個例外是在整數除法且為除數 0 時所引發的例外,您可以讓浮點數運算除數為 0 時也丟出這個例外。
public class ThrowDemo {
public static void main(String[] args) {
try {
double data = 100 / 0.0;
System.out.println("浮點數除以零:" + data);
if(String.valueOf(data).equals("Infinity"))
throw new ArithmeticException("除零例外");
}
catch(ArithmeticException e) {
System.out.println(e);
}
}
}
在檢驗運算結果為 Infinity 時,您自行建立 ArithmeticException 實例並使用 "throw" 丟出,產生實例的同時您可以指定訊息,執行結果如下:
浮點數除以零:Infinity
java.lang.ArithmeticException: 除零例外
在巢狀的 try...catch 結構時,必須注意該例外是由何者引發並由何者捕捉,例如:
public class CatchWho {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"ArrayIndexOutOfBoundsException" +
"/內層try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"ArrayIndexOutOfBoundsException" +
"/外層try-catch");
}
}
}
執行結果:
ArrayIndexOutOfBoundsException/內層try-catch
發生ArithmeticException
在範例 10.4 中,丟出的 ArrayIndexOutOfBoundsException 由內層的 "catch" 先捕捉到,由於內層已經捕捉了例外,所以外層的 "catch" 並不會捕捉到 ArrayIndexOutOfBoundsException 例外,如果內層的 "catch" 並沒有捕捉到這個例外,則外層的 "catch" 就有機會捕捉這個例外,例如範例 10.5 中 ArrayIndexOutOfBoundsException 就會被外層的 "catch" 捕捉到。
public class CatchWho2 {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArithmeticException e) {
System.out.println(
"ArrayIndexOutOfBoundsException" +
"/內層try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"ArrayIndexOutOfBoundsException" +
"/外層try-catch");
}
}
}
執行結果:
ArrayIndexOutOfBoundsException/外層try-catch
如果您在方法中會有例外的發生,而您並不想在方法中直接處理,而想要由呼叫方法的呼叫者來處理,則您可以使用 "throws" 關鍵字來宣告這個方法將會丟出例外,例如 java.ioBufferedReader 的 readLine() 方法就聲明會丟出 java.io.IOException。使用 "throws" 聲明丟出例外的時機,通常是工具類別的某個工具方法,因為作為被呼叫的工具,本身並不需要將處理例外的方式給定義下來,所以在方法上使用"throws"聲明會丟出例外,由呼叫者自行決定如何處理例外是比較合適的,您可以如下使用 "throws" 來丟出例外:
private void someMethod(int[] arr) throws
ArrayIndexOutOfBoundsException,
ArithmeticException {
// 實作
}
注意方法上若會丟出多種可能的例外時,中間是使用逗點分隔;當方法上使用 "throws" 宣告丟出例外時,意味著呼叫該方法的呼叫者必須處理這些例外,範例 10.6 是 "throws" 的簡單示範。
public class ThrowsDemo {
public static void main(String[] args) {
try {
throwsTest();
}
catch(ArithmeticException e) {
System.out.println("捕捉例外");
}
}
private static void throwsTest()
throws ArithmeticException {
System.out.println("這只是一個測試");
// 程式處理過程假設發生例外
throw new ArithmeticException();
}
}
執行結果:
這只是一個測試
捕捉例外
簡單的說,您要不就在方法中直接處理例外,要不就在方法上宣告該方法會丟回例外,由呼叫它的呼叫者來處理例外。
良葛格的話匣子 您也可以在定義介面(interface)時於方法上聲明"throws"某些類型的例外,然而要小心使用,因為若您在這些方法中發生了某些不是方法聲明的例外,您就無法將之"throw",只能自行撰寫一些try..catch來暗自處理掉,或者是重新包裝例外為"throws"上所聲明的例外,或者是將該例外包裝為RuntimeException然後再丟出。