Java 程式語言有許多的優點,其中一項是 強韌(Robust) ,除了沒有指標(Point)之外,達成強韌這個特性地還有 例外處理(Exception Handling),這個重要的機制。
當編譯器覺得你所寫的 Java 程式,某些陳述式會有潛在的危險會造成程式中斷執行時,就會要求你做適當的處理,也就是使用 try-catch 陳述式來將不安全的程式碼給包起來,並指定例外處理函式來處理這些例外,例如:
package idv.jacky.ironman4.day13;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Day13Example1 {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String number1;
int int1;
String number2;
int int2;
double answer;
while (true) {
try {
System.out.print("請輸入數字1 > ");
number1 = in.readLine();
int1 = Integer.parseInt(number1);
System.out.print("請輸入數字2 > ");
number2 = in.readLine();
int2 = Integer.parseInt(number2);
answer = int1 / int2;
System.out.printf("%d / %d = %.2f %n", int1, int2, answer);
} catch (IOException e) {
e.printStackTrace();
} catch (NumberFormatException ne) {
ne.printStackTrace();
} catch (ArithmeticException ae) {
ae.printStackTrace();
}
}
}
}
上面這個程式,大家應該蠻熟悉的,因為用了許多前面幾天用過的程式碼。首先我們要使用者分別輸入兩個整數,在第20和24行,InputStreamReader 的 readLine 方法會丟出 IOException,所以我們必需處理它(第29行)。readLine方法讀進來的是個字串(String),我們又用 Integer.parseInt 方法,將字串轉成 int 型態(第21和25行)。Integer.parseInt 方法之前也提到過,當輸入的字串不是正確的數字格式時,會丟出 NumberFormatException,我們一樣處理它(註1)。最後,我們將第一個數字除以第二個數字(第26行),然後印出結果(第28行)。在 Java 裡,兩個整數相除,如果除數為 0 的話,會丟出 ArithmethicExpcetion(註1),我們在第33行來處理。
一小段程式碼寫下來,可能要處理好幾個例外,往往我們偷懶,又或是暫時沒空處理,又真的不需要特別處理,catch 那段的程式碼裡,我們往往就空著或是直接叫 Java 列印出例外堆疊 (把例外發生的過程印出來)。所以程式碼就會像上面這樣。
如果例外真的不需要特別處理的話,但又不想寫那麼多個 catch 陳述式,Java SE 7 裡提供了一個新的方法,請看下面的例子:
package idv.jacky.ironman4.day13;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Day13Example2 {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String number1;
int int1;
String number2;
int int2;
double answer;
while (true) {
try {
System.out.print("請輸入數字1 > ");
number1 = in.readLine();
int1 = Integer.parseInt(number1);
System.out.print("請輸入數字2 > ");
number2 = in.readLine();
int2 = Integer.parseInt(number2);
answer = int1 / int2;
System.out.printf("%d / %d = %.2f %n", int1, int2, answer);
} catch (IOException | NumberFormatException | ArithmeticException e) {
e.printStackTrace();
}
}
}
}
是的,往上面的程式碼中,你可以很清楚地看到我們用 or 符號(|),將三個例外串在一起,這樣就可以省掉兩個 catch 陳述式了。
註:NumberFormatException 和 ArithmeticException 都是RuntimeException 的子類別,也就是說在編譯時期,不像 IOException 會被要求一定要處理。所以你不處理這兩個例外,程式也是可以正確的編譯和執行的,可是只要一有例外發生,整個程式就會中斷執行。