Professional Documents
Culture Documents
Java Thai
Java Thai
faa)
ในบทที่เจ็ดนี้เราจะพูดถึงการใช และการออกแบบ exception หรือที่เรียกวาการควบคุมและดัก
จับ error ที่อาจเกิดขึ้นในการ compile และ run โปรแกรม
หลังจากจบบทนี้แลว ผูอานจะไดทราบถึง
o ความหมายของ exception
o วิธีการใชและควบคุม exception
o การใช throws และ try
o การออกแบบ และใช exception ที่เขียนขึ้นเอง
o การใช assertion
7.1การตรวจสอบ error
Exception โดยปกติจะเปน object จาก sub class (class ใด class หนึ่ง) ของ class
Throwable ที่ Java มีให และ class หลัก ๆ สอง class ที่เกิดจาก class Throwable โดยตรงที่
Throwable
Error Exception
1: /**
2: Throwing exception when divided by zero
3: */
4:
5: import static java.lang.System.out;
6:
7: class ThrowException {
8: public static void main(String[] args) throws Exception {
9: int number = 10;
10: int divider = 0;
11:
12: out.printf("Divide %d by %d%n", number, divider);
13: int result = number / divider;
14: out.printf("Result is %d%n", result);
15: }
16: }
Divide 10 by 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ThrowException.main(ThrowException.java:13)
232
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
1: /**
2: Manipulate error with try and catch
3: */
4:
5: import static java.lang.System.out;
6:
7: class TryAndCatchExample1 {
8: public static void main(String[] args) {
9: int number1 = 15;
10: int number2 = 0;
11:
12: try {
13: out.println("Division by zero in a try block.");
14: int result = number1 / number2;
15: //line below won't get executed
16: out.println("Leaving a try block.");
17: }
18: catch(ArithmeticException ex) {
19: out.println("Exception caught in a catch block.");
20: }
21:
22: out.println("After a try block.");
23: }
24: }
out.println(ex.getMessage());
ex.printStackTrace();
233
เริ่มตนการเขียนโปรแกรมดวย Java
java.lang.ArithmeticException: / by zero
at TryAndCatchExample1.main(TryAndCatchExample1.java:14)
After a try block.
…
…
out.println("Leaving a try block.");
}
out.pritnln("In between try and catch blocks.");
catch(ArithmeticException ex) {
…
…
ตัวอยางการใช try และ catch ที่ classic อีกอันหนึ่งก็คือ การใช try และ catch ใน loop ดัง
ตัวอยางตอไปนี้
1: /**
2: Using try and catch in a loop
3: */
4:
5: import static java.lang.System.out;
6:
7: class TryAndCatchExample2 {
8: public static void main(String[] args) {
9: int number = 10;
10:
11: for(int index = 5; index >= -1; index--)
12: try {
13: out.printf("try block: index = %d%n", index);
14: int result = number / index;
15: out.println("Leaving a try block.");
16: }
17: catch(ArithmeticException e) {
18: out.println("Exception caught in catch block.");
19: out.println(e.getMessage());
20: e.printStackTrace();
21: }
22:
23: out.println("After a try and catch blocks.");
24: }
25: }
234
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
1: /**
2: Using NumberFormatException
3: */
4:
5: import static java.lang.System.out;
6:
7: class NumFormatException {
8: public static void main(String[] args) {
9: int number, sum = 0;
10:
11: for(int i = 0; i < args.length; i++) {
12: try {
13: number = Integer.parseInt(args[i]);
14: sum += number;
15: }
16: //ignore input that's not a number
17: catch(NumberFormatException e) {
18: e.printStackTrace(System.out);
19: }
20: }
21: out.printf("Sum is %d%n", sum);
22: }
23: }
D:\>java NumFormatException
1 2 3 r 5 6 t y
java.lang.NumberFormatException: For input string: "r"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at NumFormatException.main(NumFormatException.java:13)
java.lang.NumberFormatException: For input string: "t"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at NumFormatException.main(NumFormatException.java:13)
java.lang.NumberFormatException: For input string: "y"
at java.lang.NumberFormatException.forInputString(Unknown Source)
235
เริ่มตนการเขียนโปรแกรมดวย Java
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at NumFormatException.main(NumFormatException.java:13)
try {
…
…
}
catch(Exception e) {
…
…
}
catch(ArithmeticException ex) {
…
…
}
เนื่องจากวา class ArithmeticException เปน class ที่เกิดมาจาก class Exception ดังนัน ้ error
ที่เกิดขึ้นก็จะถูกดักจับใน catch block ทั้งหมด การดักจับใน catch block ที่สองจึงไมเกิดขึ้น
1: /**
2: Catching multiple errors
3: */
4:
5: import static java.lang.System.out;
6:
7: class MultipleCatches {
8: public static void main(String[] args) {
9: //force divide by zero at index = 2
10: int []number = {1, 2, 0, 4};
11: int num = 12;
12: int count = 0;
13:
14: //force array index out of bound at index = 4
15: for(int i = 0; i < number.length + 1; i++) {
16: try {
17: num /= number[i];
18: out.printf("result = %d%n", num);
19: }
20: catch(ArithmeticException e) {
21: out.println("error message: " + e.getMessage());
22: }
23: catch(ArrayIndexOutOfBoundsException e) {
24: out.println("error message: " + e.getMessage());
25: }
26: finally {
27: out.printf("In finally block #%d%n", count++);
28: }
29: }
30: out.println("After a for loop.");
31: }
32: }
result = 12
In finally block #0
result = 6
In finally block #1
236
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
Java ยังมี block อีก block หนึ่งที่เอาไวดักจับ error ที่เกิดขึ้น ที่ซึ่งเปน block สุดทายของการ
catch ทั้งหมด โดยกําหนดให block นี้ทีชื่อวา finally (บรรทัดที่ 26 ของโปรแกรม
MultileCatches.java)
1: /**
2: Using throw with try/catch block
3: */
4:
5: import java.util.Scanner;
6: import java.io.*;
7: import static java.lang.System.out;
8:
9: class ThrowsWithTry {
10: public static void main(String[] args) throws IOException {
11: Scanner input = new Scanner(System.in);
12: int first, divider;
13:
14: //keep looping until error occur
15: while(true) {
16: out.print("Enter a number: ");
17: //get first number
18: first = input.nextInt();
19: //get second number
20: out.print("Enter a divider: ");
21: divider = input.nextInt();
22: //try dividing first by divider
23: try {
24: double result = first / divider;
25: out.println("Result = " + result);
26: }
27: catch(ArithmeticException e) {
28: out.println("Exception: " + e.getMessage());
29: e.printStackTrace();
30: }
31: }
32: }
33: }
โปรแกรมจะหยุดการทํางานก็ตอเมื่อผูใชใสขอมูลที่ไมใชตัวเลข และจะทําการฟองถาขอมูลตัวที่
สองของการหารมีคาเปนศูนย ผลลัพธที่ไดจากการ run คือ
237
เริ่มตนการเขียนโปรแกรมดวย Java
D:\>java ThrowsWithTry
Enter a number: 23
Enter a divider: 12
1: /**
2: Using throws and try together
3: */
4:
5: import static java.lang.System.out;
6: import java.util.Scanner;
7: import java.util.InputMismatchException;
8:
9: class ThrowsWithTry1 {
10: public static void main(String[] args) {
11: Scanner input = new Scanner(System.in);
12: int first, divider, result;
13: boolean done = false;
14:
15: //continue till acceptable input is entered
16: while(!done) {
17: try {
18: out.print("Enter a number: ");
19: first = input.nextInt();
20: out.print("Enter a divider: ");
21: divider = input.nextInt();
22:
23: result = first / divider;
24: out.printf("Result is %d%n", result);
25: done = true;
26: }
27: catch(InputMismatchException ie) {
28: out.printf("Exception: %s%n", ie);
29: //discard this input
30: input.nextLine();
31: out.println("Try again.");
32: }
33: catch(ArithmeticException ar) {
34: out.printf("Exception: %s%n", ar);
35: out.println("Zero not accepted.");
36: }
37: }
38: }
39: }
ผลลัพธที่เราไดคือ
D:\>java ThrowsWithTry1
Enter a number: 3
238
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
Enter a divider: e
Exception: java.util.InputMismatchException
Try again.
1: /**
2: Using user's exception
3: */
4:
5: import java.util.Scanner;
6: import java.util.InputMismatchException;
7: import static java.lang.System.out;
8:
9: class TestInputValidation {
10: public static void main(String[] args) {
11: Scanner input = new Scanner(System.in);
12: int first, divider, result;
13: boolean done = false;
14:
15: //continue till acceptable input is entered
16: while(!done) {
17: try {
18: out.print("Enter a number: ");
19: first = input.nextInt();
20: out.print("Enter a divider: ");
21: divider = input.nextInt();
22:
23: result = divide(first, divider);
24: out.printf("Result is %d%n", result);
25: done = true;
26: }
27: catch(InputMismatchException ie) {
28: out.printf("Exception: %s%n", ie);
29: //discard this input
30: input.nextLine();
31: out.println("Try again.");
32: }
33: catch(ZeroDivideException ar) {
34: out.printf("Exception: %s%n", ar);
35: out.println("Zero not accepted.");
36: }
37: }
38: }
39:
40: //division of two numbers
41: //if n is 0, ZeroDivideException is thrown
42: public static int divide(int m, int n) throws ZeroDivideException {
43: int result;
239
เริ่มตนการเขียนโปรแกรมดวย Java
44: try {
45: result = m / n;
46: }
เราไดเปลี่ยนโปรแกรมกอนหนานี้มากพอสมควรในการที่จะอานขอมูลใหถูกตอง พรอมทั้งแสดง
ถึงการเขียน exception ขึ้นมาใชเอง เราเริ่มดวยการสราง method readInt() ขึ้นมาใหม โดย
กําหนดใหผูใชตองใสขอมูลใหถูกตอง ถาไมถูกเราก็จะวนกลับไปถามใหมจนกวาจะได
catch(ArithmeticException e) {
throw new ZeroDivideException(); //throw new exception
}
1: /**
2: Exception for division by zero
3: */
4:
5: class ZeroDivideException extends Exception {
6: //default constructor
7: ZeroDivideException() {
8: super("divide by zero"); //call super class' constructor
9: }
10:
11: ZeroDivideException(String message) {
12: super(message);
13: }
14: }
…
catch(InputMismatchException ie) {
out.printf("Exception: %s%n", ie);
//discard this input
input.nextLine();
out.println("Try again.");
}
catch(ZeroDivideException ar) {
out.printf("Exception: %s%n", ar);
out.println("Zero not accepted.");
}
D:\>java TestInputValidation
Enter a number: 23
Enter a divider: 0
Exception: ZeroDivideException: divide by zero
240
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
1: /**
2: Catching error within a given range
3: */
4:
5: import java.util.Scanner;
6: import static java.lang.System.out;
7:
8: class CheckRange {
9: public static void main(String[] args) {
10: Scanner input = new Scanner(System.in);
11:
12: try {
13: out.print("Enter start number: ");
14: int first = input.nextInt();
15: out.print("Enter end number: ");
16: int second = input.nextInt();
17: out.print("Enter number to check: ");
18: int third = input.nextInt();
19:
20: //check if the third is between first and second
21: checked(first, second, third);
22: out.printf("Number %d is in [%d, %d]%n", third, first, second);
23: }
24: catch(OutOfRangeException e) {
25: e.printStackTrace(System.err);
26: }
27: }
28:
29: //method to validate range
30: public static void checked(int start, int stop, int num)
throws OutOfRangeException {
31: if(num < start) {
32: String errMsg = new String(num + " < " + start);
33: throw new OutOfRangeException(errMsg, start, stop);
34: }
35: if(num > stop) {
36: String errMsg = new String(num + " > " + stop);
37: throw new OutOfRangeException(errMsg, start, stop);
38: }
39: }
40: }
1: /**
2: OutOfRangeException.java
3: */
4:
5: public class OutOfRangeException extends Exception {
6: //default constructor
7: OutOfRangeException() {}
8:
9: //constructor
241
เริ่มตนการเขียนโปรแกรมดวย Java
1: /**
2: Catching error within a given range
3: */
4:
5: import java.util.Scanner;
6: import static java.lang.System.out;
7:
8: class AssertionTest {
9: public static void main(String[] args) {
10: Scanner input = new Scanner(System.in);
11:
12: out.print("Enter start number: ");
13: int first = input.nextInt();
14: out.print("Enter end number: ");
15: int second = input.nextInt();
16: out.print("Enter number to check: ");
17: int third = input.nextInt();
18:
19: //check if the third input is between first and second
20: assert(third >= first && third <= second) :
message(first, second, third);
21: out.printf("Number %d is in [%d, %d]%n", third, first, second);
22: }
23:
24: //check if p is in [m, n]
25: public static String message(int m, int n, int p) {
26: return String.format("%d is not in [%d, %d]%n", p, m, n);
27: }
28: }
242
บทที่ 7: การตรวจสอบและดักจับ Error (Exceptions)
at AssertionTest.main(AssertionTest.java:20)
สรุป
แบบฝกหัด
1
Debug เปนการตรวจสอบขอผิดพลาดที่อาจเกิดขึ้นในขณะที่มีการเขียนโปรแกรมเกิดขึ้น ซึ่งเปนการตรวจสอบถึงความ
ถูกตองของโปรแกรมกอนที่จะเสร็จสิ้น ซึ่งตางจากการสงขอความเตือน user (error message) ถึงขั้นตอนหรือขอมูลที่
ไมตรงกับสิ่งที่โปรแกรมตองการ
243
เริ่มตนการเขียนโปรแกรมดวย Java
2. จงปรับปรุงโปรแกรมที่เขียนขึ้นในขอหนึ่ง โดยเพิ่มการตรวจสอบที่ไมรับตัวเลขที่ต่ํากวาศูนย
CELSIUS FAHRENHEIT
0 32.0
10 50.0
20 68.0
30 86.0
40 104.0
50 122.0
60 140.0
70 158.0
80 176.0
90 194.0
100 212.0
>java Temperature 40 20 5
Ordering Err FIRST = 40 SECOND = 20
>java Temperature 10 40
java.lang.ArrayIndexOutOfBoundsException:
at Temperature.main(Temperature.java:41)
244