來看一個簡單的程式,使用者可以連續輸入整數,最後輸入0結束後會顯示輸入數的平均值:
package cc.openhome;
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double sum = 0;
int count = 0;
int number;
while(true) {
number = scanner.nextInt();
if(number == 0) {
break;
}
sum += number;
count++;
}
System.out.printf("平均 %.2f%n", sum / count);
}
}
如果使用者正確地輸入每個整數,程式會如預期地顯示平均:
10 20 30 40 0
平均 25.00
平均 25.00
如果使用者不小心輸入錯誤,那就會出現奇怪的訊息,例如第三個數輸入為3o,而不是30了:
10 20 3o 40 0
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at cc.openhome.Average.main(Average.java:11)
Java Result: 1
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at cc.openhome.Average.main(Average.java:11)
Java Result: 1
這段錯誤訊息對除錯是很有價值的,不過先看到錯誤訊息的第一行:
Exception in thread "main" java.util.InputMismatchException
Scanner
物件的nextInt()
方法,可以將使用者輸入的下一個字串剖析為int
值,如果出現InputMismatchException錯
誤訊息,表示不符合Scanner
物件預期,因為Scanner
物件預期下一個字串本身要代表數字。Java中所有錯誤都會被包裹為物件,如果你願意,可以嘗試(
try
)捕捉(catch
)代表錯誤的物件後作一些處理。例如:package cc.openhome;
import java.util.*;
public class Average2 {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
double sum = 0;
int count = 0;
int number;
while (true) {
number = scanner.nextInt();
if (number == 0) {
break;
}
sum += number;
count++;
}
System.out.printf("平均 %.2f%n", sum / count);
} catch (InputMismatchException ex) {
System.out.println("必須輸入整數");
}
}
}
這邊使用了
try
、catch
語法,JVM會嘗試執行try
區塊中的程式碼,如果發生錯誤,執行流程會跳離錯誤發生點,然後比對catch
括號中宣告的型態,是否符合被拋出的錯誤物件型態,如果是的話,就執行catch
區塊中的程式碼。一個執行無誤的範例如下所示:
10 20 30 40 0
平均 25.00
平均 25.00
範例中如果nextInt()
發生InputMismatchException
,流程就會跳到型態宣告為InputMismatchException
的catch
區塊,執行完catch
區塊後,之後沒有其它程式碼了,所以程式就結束了。一個執行時輸入有誤的範例如下所示:
10 20 3o 40 0
必須輸入整數
必須輸入整數
這個範例示範了如何運用try
、catch
,在錯誤發生時顯示更友善錯誤訊息。有時錯誤可以在捕捉處理之後,嘗試回復程式正常執行流程。例如:
package cc.openhome;
import java.util.*;
public class Average3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double sum = 0;
int count = 0;
int number;
while (true) {
try {
number = scanner.nextInt();
if (number == 0) {
break;
}
sum += number;
count++;
} catch (InputMismatchException ex) {
System.out.printf("略過非整數輸入:%s%n", scanner.next());
}
}
System.out.printf("平均 %.2f%n", sum / count);
}
}
如果nextInt()
發生了InputMismatchException
錯誤,執行流程就會跳到catch
區塊,執行完catch
區塊之後,由於還在while
迴圈中,所以還可繼續下一個迴圈流程。
一個輸入錯誤時的結果示範如下,對於正確的整數輸入予以加總,對於錯誤的輸入則顯示略過,最後顯示平均值:
10 20 3o 40 0
略過非整數輸入:3o
平均 23.33
略過非整數輸入:3o
平均 23.33
不過就Java在例外處理的設計上,並不鼓勵捕捉
InputMismatchException
並重新恢復執行流程,原因在介紹例外繼承架構時會進行說明。