26
การดักจับขอผิดพลาด Exception Handling วัตถุประสงค เพื่อใหผูเรียนเขาใจหลักการทํางานการดักจับขอผิดพลาดของการเขียนโปรแกรมเชิงวัตถุ เพื่อใหผูเรียนสามารถนําหลักการทํางานการดักจับขอผิดพลาดของการเขียนโปรแกรมเชิง วัตถุไปประยุกตใชเขียนโปรแกรมจริงได บทที 11

บทที่ 11 การดักจับข

  • Upload
    -

  • View
    32

  • Download
    0

Embed Size (px)

Citation preview

การดักจับขอผิดพลาด Exception Handling

วัตถุประสงค

♦ เพื่อใหผูเรียนเขาใจหลักการทํางานการดักจับขอผิดพลาดของการเขียนโปรแกรมเชงิวัตถ ุ♦ เพื่อใหผูเรียนสามารถนําหลกัการทํางานการดักจับขอผดิพลาดของการเขียนโปรแกรมเชิง

วัตถุไปประยุกตใชเขียนโปรแกรมจริงได

บทที ่

11

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

245

เนื้อหาบทเรยีน

♦ การดักจับขอผิดพลาด ♦ คําสั่ง try ♦ คําสั่ง catch ♦ คําสั่ง final ♦ คําสั่ง throw, throws ♦ การสรางคลาสตรวจจับขอผิดพลาดใชเอง

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

246

ความผดิปกต(ิException) Exception คือ เหตุการณผิดปกติที่เกิดขึ้น สงผลใหการทํางานของโปรแกรมไมเปนไปตามขั้นตอนที่ไดกําหนดไว ตัวอยางของการเกิด Exception เชน เมื่ออางถึงตัวแปรอารเรยเกินขนาดที่กําหนด หรือการหารดวยตัวเลข 0 เปนตน โดย exception แบงออกเปนหลายประเภท ซ่ึง exception แตละประเภทจะเปนคลาสลูกของ คลาส Exception ดังรูปตอไปนี้ ตัวอยาง Exception ที่เกิดขึ้นขณะรันโปรแกรม โดยโปรแกรมีการ / ดวย 0 public class Error1 { public static void main(String[] args) { int x = 5 / 0; System.out.println("Result = " + x); } } โปรแกรมนี้เมือ่คอมไพลจะไมเกิดขอผิดพลาด ผลลัพธที่ไดจากการรันโปรแกรม java.lang.ArithmeticException: / by zero at Error1.main(Error1.java:3) Exception in thread "main"

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

247

ตัวอยาง การเกิด Exception ขณะ array เกินขนาดที่จองไว public class Error2 { public static void main(String[] args) { int x[] = {0,1,2}; for (int i =0; i <= x.length ; i++ ) { System.out.println("Result = " + x[i]); } System.out.println(“Good bye”); } } เมื่อผานการคอมไพล ผลลัพธที่ไดจากการรันโปรแกรมคือ

Result = 0 Result = 1 Result = 2

java.lang.ArrayIndexOutOfBoundsException: 3 at Error2.main(Error2.java:6) Exception in thread "main"

จากการรันโปรแกรมนี้จะพบวาหากโปรแกรมไมเกิดขอผิดพลาดกอน จะพิมพขอความวา Good bye ออกบนหนาจอ แตโปรแกรมนี้ พิมพขอความ result = 0 result =1 result =2 แลวก็หยุดไป พรอมกับแสดงขอความ java.lang.ArrayIndexOutOfBoundsException: 3 แสดงวาโปรแกรมเกิดขอผิดพลาดขณะรันโปรแกรม(runtime exception) ที่ช่ือวา ArrayIndexOutOfBoundsException ขึ้นกอนทําใหโปรแกรมหยุดการทํางานไป การเกิด Exception ใน Java o เมื่อเกิด Exception ขึ้นในภาษา Java ตัว JVM จะสรางออปเจ็คในตระกลูของ Throwable Class

ขึ้นมาแลวโยนออกมา o เมื่อ JVM โยนออปเจ็ค Exception ออกมาเราสามารถดักจับดวยคําสั่ง try, catch, finally แตถา

เราไมจัดการ JVM ก็จะเปนคนจัดการเองคอืแสดงการเกดิ Exception และก็ลุดออกโปรแกรมดังตัวอยางขางตน

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

248

Exception Hierarchy จะแบงออกเปน 3 กลุมดวยกัน ► จะแบงออกเปน 3 กลุมดวยกนั

Error เปน Exception ที่เกิดขึ้นจาก JVM เองไมเกี่ยวกับการโปรแกรมของเรา เชน StackOverflowError, OutOfMemoryError

RuntimeException เปน Exception ที่เกิดจากการโปรแกรมของเราซึ่งถาเกิด Exception ในตระกลูนี้ควรจะแกไขโปรแกรมโดยไมใช try – catch - finally เชน ArithmeticException, NullPointerException, IndexOutOfBoundsException

Exception เปน Exception ที่จะตองดกัจบัเชน FileNotFoundException, EOFException วิธีการจัดการกับ Exception Exception สามารถเกิดขึ้นไดกับโปรแกรมเสมอ ทุกที่ทุกเวลา ดังนัน้เพื่อใหโปรแกรมของเราทํางานจบอยางปกติแมวาจะเกิดขอผิดพลาดเหลานั้น โดยเราจะตองจัดการกับขอผิดพลาด(Exception Handing) ที่อาจเกิดขึน้ในโปรแกรม โดยระบุการดกัจับ exception ไวในสวนที่คาดวาจะเกิดขอผิดพลาด และทําการจดัการกับ exception ดังกลาว ดวยคําสั่ง Try ,catch ,throw หรือ finally คําสั่ง try, catch and finally

ใชในการดักจบั Exception ที่เกิดขึ้นจากการเรียกใช Methods หรือ คําสั่ง เมื่อเราจับ Exception ที่เกิดขึ้นแลว Exception ก็จะหายไปโปรแกรมก็จะทํางานตอโดยขามคําสั่งในบล็อกไป

Error Exception

RuntimeException

Object

Throwable

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

249

ขอกําหนด

เราจะนํา code ที่เราคิดวาอาจจะเกิดขอผิดผลาดมาไวในบล็อก try ถาเกดิขอผิดผลาดหรือ Exception ก็จะถูกจับโดยบล็อกของ catch หลักการทํางาน

เมื่อเกิดขอผิดผลาดในบล็อกของ try JVM ก็จะโยน Exceptin มาใหกับบล็อกของ catch ตัวอยาง การใชดักจับขอผิดพลาดที่อาจเกิดขึ้น class Zero{ public static void main(String args[]) { int numerator = 10; int denominator = 0; System.out.println("This test devide by zero"); try { System.out.println(numerator/denominator); } catch(ArithmeticException e) { System.out.println("Arithemetic Exception"); System.out.println("Cann't compute"); } System.out.println("This text will not be printed."); } }

ผลลัพธที่ไดคือ This test devide by zero Arithemetic Exception Cann't compute This text will not be printed.

รูปแบบการใชงาน try และ catch try{

[statements] }

[catch( ExceptionType1 ExceptionName1) { [statements]

}]

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

250

ตัวอยาง การใชดักจับขอผิดพลาดที่อาจเกิดขึ้น class Zero{

public static void main(String args[]) { int numerator = 10; int denominator = 0; System.out.println("This test devide by zero"); try { System.out.println(numerator/denominator); } catch(Exception e) { System.out.println(e.toString()); } System.out.println("This text will not be printed."); }

} ผลลัพธที่ไดคือ This test devide by zero Arithemetic Exception java.lang.ArithmeticException: / by zero This text will not be printed.

ตัวอยาง การใชดักจับขอผิดพลาดที่อาจเกิดขึ้น public class Error2 { public static void main(String[] args) { int x[] = {0,1,2}; try{ for (int i =0; i <= x.length ; i++ ) System.out.println("Result = " + x[i]); } catch (Exception e){ System.out.println("GO GOOOO"); } } }

ผลลัพธที่ไดคือ Result = 0 Result = 1 Result = 2 GO GOOOO

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

251

ตัวอยาง การใชดักจับขอผิดพลาดท ี่ไมถูกตอง try {

System.out.println(“in of try block”); } System.out.println(“out of try block”); // ขาด block try

ตัวอยาง การใชดักจับขอผิดพลาดที่อาจเกิดขึ้น

try { System.out.println(“in of try block”);

} System.out.println(“out of try block”); // error เพราะ try ตองตามดวย catch ทันที catch ( Exception e ) {

System.out.println(“in of catch block”); }

ขอกําหนด - ถามี catch บล็อกหลายตัว ExceptionType จะตองไมซํ้ากันและจะตองจัดเรียงตาม Hierarchy

ดวย โดย Hierarchy ที่ต่ํากวาจะอยูดานบน Hierarchy ที่สุดกวาจะอยูดานลาง หลักการทํางาน

พิจารณา Exception วา ExceptionType ที่โยนมานั้น ตรงหรือใกลเคียงกับ ExceptionType ใดที่สุดในบล็อกของ catch

รูปแบบการใช Try คูกับ หลาย Catch try {

<statements> } catch (<ExceptionType1> <identifier>) { <statements> } catch(<ExceptionType2> <identifier>) { <statements> }

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

252

ตัวอยางคลาส Exception มาตราฐาน เชน IOException , NoSuchMethodException , FileNotFoundExceptionฯ ซ่ึงคลาสเหลานี้ตองทําการ import java.io.IOException; หรืออ่ืนๆ ตามลําดับ ถาไมรูจะตองดักจับ Exception อะไรบาง.... ทําอยางไรด ี

การดักจับ exception ไมใชเร่ืองยากก็จริง แตเร่ืองที่ยากคือ การที่เราไมรูวามี exception อะไรบางที่จะตองดักจับ ตรงนี้หากเขียนโปรแกรมไปสักพัก มีความชํานาญมากพอ แลวคงจะทําใหทราบไดเองจากประสบการณวาจะตองดักจับ exception ประเภทใดบาง แต ณ ตอนนี้หากไมทราบจริงๆ วาจะตองดักจับ exception อะไรบาง วิธีที่งายที่สุด คือ ใหดักจับ exception ประเภท Exception เพราะ exception ทุกประเภทที่เกิดขึ้นในโปรแกรม ลวนเปน ออบเจ็คของคลาสที่สืบทอดคุณสมบัติมาจากคลาส Exception ทั้งสิ้น(จะสืบทอดโดยตรงหรือไม ไมใชเร่ืองสําคัญ) ดังนั้นไมวาจะเกิด exception ประเภทใดขึ้นหากระบุใหดักจับ exception ประเภท Exception แลวจะสามารถดักจับไดทั้งหมด ตัวอยาง การดักจับขอผิดพลาด class testException{ public static void main(String[] args) { int x[] = {1, 10, 22}; for(int i = 0; i <= 3; i++) try{ System.out.println(x[i] / i ); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Error!!! array out of bound"); } catch(ArithmeticException e){ System.out.println("Error!!! divided by ZERO"); } catch(Exception e){ System.out.println("Error!!! Something..."); } System.out.println("Bye Bye");

}} ผลลัพธที่ไดคือ Error!!! divided by ZERO 10 11 Error!!! array out of bound Bye Bye

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

253

ตัวอยาง การดักจับขอผิดพลาด import javax.swing.JOptionPane; class DivByZero{ public static void main(String args[]){ String s1, s2; int i1 , i2; try{ s1 = JOptionPane.showInputDialog("Enter number 1 : "); s2 = JOptionPane.showInputDialog("Enter number 2 : "); i1 = Integer.parseInt(s1); i2 = Integer.parseInt(s2); JOptionPane.showMessageDialog(null, Integer.toString(i1 / i2)); } catch (NumberFormatException e){//1 JOptionPane.showMessageDialog(null,e.getMessage()); System.exit(0); } catch(ArithmeticException e){//2 JOptionPane.showMessageDialog(null,e.getMessage()); System.exit(0); }

catch(Exception e){//3 JOptionPane.showMessageDialog(null,e.getMessage()); System.exit(0); } System.exit(0); } } จากโปรแกรมจะทําการแสดง Dialog box เพื่อรับตัวเลขจาํนวน 2 คร้ัง แลวนําตวัแรกเปนตัวตั้ง

แลวเอาคาที่สองเปนตัวหาร ซ่ึงโปรแกรมไดทําการดกัจบั error ไว 2 รูปแบบและหากเกิดขอผิดพลาดจากนั้นจะกระทําใน Exception ที่ 3

ตัวอยางที่ผิด

try { RandomAccessFile raf = new RandomAccessFile(“myfile.txt”, “r”); byte b[] = new byte[1000]; raf.readFully(b, 0, 1000);

} catch ( IOException e ) {

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

254

System.out.println(“IO Error”); } catch ( FileNotFoundException e ) {

System.out.println(“File not found”); } ผิดเนื่องจาก FileNotFoundException เปน sup class ของ IOException ดังนี ้

ใหถูกตองเปลีย่นเปน

try { RandomAccessFile raf = new RandomAccessFile(“myfile.txt”, “r”); byte b[] = new byte[1000]; raf.readFully(b, 0, 1000);

} catch ( FileNotFoundException e ) { System.out.println(“File not found”);

} catch ( IOException e ) { System.out.println(“IO Error”);

}

การใช try-catch block อยางปกติ จะทําใหการดําเนินของโปรแกรมผานเขามาที่จุดเดียวและผาน

ออกไปที่จุดเดียว แตหากใน try block หรือ catch block มีการใชประโยคควบคุมที่ทําใหการดําเนินของโปรแกรมกระโดดออกไปจากเสนทางปกติ เชน break , continue ,หรือ return ซ่ึงไมสามารถคาดเดาไดลวงหนาวาโปรแกรมจะดําเนินออกไปจาก try-catch ที่จุดใด ในลักษณะเชนนี้ถามีโปรแกรมที่ตองทํางานหลังจากจบ try-catch block นั้น เชน การปดไฟลหรือ ปด socket หรือการคืนหนวยความจําของ graphic หากนําโปรแกรมเหลานี้มาไวตอจาก catch block ก็จะทําใหโปรแกรมเหลานี้ไมถูกทํางานในบางกรณี ดังนั้นภาษาจาวา จึงมี finally block ไวสําหรับใหโปรแกรมที่ตองถูกทํางานเสมอไมวาโปรแกรมจะดําเนินออกจาก try-catch block ในเสนทางใด

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

255

ขอกําหนด - ถามีบล็อก try จําเปนตองมีบล็อก catch อยางนอย 1 บล็อก หรือถามีมีบล็อก catch ก็ตองมี

บล็อก finally หลักการทํางาน

- เมื่อส้ินสุดการทํางานบล็อกของ try…catch แลว ไมวาจะเกดิ Exception หรือไมก็จะตองเขามาทํางานในบล็อกของ finally ทุกครั้ง

- ถึงแมจะสั่งคําสั่ง return หรือ System.exit() ใน try บล็อก หรือ catch บล็อก ก็จะตองเขามาทํางานใน Finally บล็อกทุกครั้ง

ตัวอยาง การเขียนโปรแกรมที่มีการดักจบั โดยใช Try – catch – finally public class Error4 { public static void main(String[] args) { try{int x = 5 / 0; System.out.println("Result = " + x); } catch(ArithmeticException a){ System.out.println("Arithmeitc Error"); } finally{ System.out.println("Finally Print"); } }}

รูปแบบการทํางาน Try , catch , finally try { …….. } catch (IOException e) { …….. } catch (Exception e) { …….. } finally { //statements placed here will always //get executed } //// ffiinnaallllyy จะทํางานทุกครั้งไมวาจะเกดิจะทํางานทุกครั้งไมวาจะเกดิ eexxcceeppttiioonn ขึ้นหรือไมก็ตามขึ้นหรือไมก็ตาม

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

256

ผลลัพธที่ไดคือ Arithmeitc Error Finally Print

ตัวอยาง การเขียนโปรแกรมที่มีการดักจบั โดยใช Try – finally public class Error4 { public static void main(String[] args) { try{

int x = 5 / 0; System.out.println("Result = " + x); } finally{ System.out.println("Finally"); } } }

ผลลัพธที่ไดคือ Finally java.lang.ArithmeticException: / by zero

at Error3.main(Error3.java:3) Exception in thread "main"

ตัวอยาง โปรแกรมที่ทําการดักจับขอผิดพลาดโดยใช try catch finally String s = null; try {

int x = s.length(); System.out.println( x );

} catch ( Exception e ) { // Exception e = Exception System.out.println(“Catch”);

} finally { System.out.println(“Finally”);

} ผลลัพธคือ Catch Finally

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

257

ตัวอยาง ที่ผิดไมควรเขยีนบล็อก finally กอน catch String s = null; try {

int x = s.length(); System.out.println( x );

} finally { System.out.println(“Finally”);

} catch ( Exception e ) { System.out.println(“Catch”);

} ผลลัพธที่ไดคือ : Compiled Error ไมสามารถเขียนบล็อก finally ไวกอนบล็อก catch

ตัวอยาง การตรวจสอบ Null String s = null; try {

int x = s.length(); System.out.println( x );

} finally { System.out.println(“Finally”);

} ผลลัพธคือ Finally Exceptoin in thread “method” java.lang.NullPointException at ClassName.method(FileName.java:15)

ตัวอยาง การตรวจจับขอผิดพลาด ดวย try catch finally class testException3{ public static void main(String[] args) { int x[] = {1, 10, 22}; try{ for(int i = 0; i <= 3; i++) System.out.println(x[i] / i ); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Error!!! array out of bound"); }

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

258

catch(ArithmeticException e){ System.out.println("Error!!! divided by ZERO"); } catch(Exception e){ System.out.println("Error!!! Something..."); } finally{ System.out.println("finally print"); } System.out.println("Bye Bye");

} } ผลลัพธที่ไดคือ Error!!! divided by ZERO finally print Bye Bye

ตัวอยาง การตรวจจับขอผิดพลาด ดวย try catch finally class testException2{ public static void main(String[] args) { int x[] = {1, 10, 22}; for(int i = 0; i <= 3; i++) try{ System.out.println(x[i] / i ); }

catch(ArrayIndexOutOfBoundsException e){ System.out.println("Error!!! array out of bound"); } catch(ArithmeticException e){ System.out.println("Error!!! divided by ZERO"); } catch(Exception e){ System.out.println("Error!!! Something..."); } finally{ System.out.println("finally print"); } System.out.println("Bye Bye");

}}

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

259

ผลลัพธที่ไดคือ Error!!! divided by ZERO finally print 10 finally print 11 finally print Error!!! array out of bound finally print Bye Bye

การจัดการ Exception ท่ีเกิดใน Method

สามารถทําได 2 แบบ o ใช try…catch…finally ดักจบั Exception ใน Methods เลย(แบบฝกหัดที่ 2) o โยน Exception ออกใหกับผูเรียก(Method)ใช โดยใช throw กับ throws

Throws Exception

หากใน method ใดมีประโยคที่อาจจะมกีารสง exception ออกมา แตไมมีการดักจับและจัดการกับ exception นั้น เราจะตองระบุให method นั้นเปน method ที่จะสง exception ออกมาโดยใช keyword ‘throws’ กํากับไวหลังจากวงเล็บของพารามิเตอร และตามดวยคลาสของ exception ที่จะถูกสงออกมา การเรียกใช method ที่ถูกระบุวาจะสง exception ออกมาจะตองมีการดกัจับและจัดการกับ exception นั้น มิเชนนั้นจะคอมไพลไมผาน

หากมี exception เกิดขึ้นในเมธอดหนึ่ง แตไมถูกดักจับภายในเมธอดนั้น จะทําให exception ถูกสงตอ(propagate) ใหกับเมธอดที่เรียกเมธอดนั้นใหทํางาน เชน method main เรียก method A ใหทํางาน และเมธอด A เรียก method B ใหทํางาน หากเกิด exception ขึ้นใน method B แต method B ไมไดดกัจบั exception นั้น โปรแกรมจะสง exception ไปให method A ตอไป และถา method A ไมดักจับ exception นั้นอีก method main ซ่ึงเปนผูเรียก method A ใหทํางานก็จะตองดักจับและจัดการกับ exception นั้น ซ่ึงเมธอด main จะหลีกเลี่ยงการดักจับ exception ไมไดแลว เพราะหากยังไมมีการดักจับ exception ที่ method main อีก จะสงผลใหโปรแกรมจบการทํางานลงแบบไมสมบูรณ สรุป

- catch คือ การดักจับ exception วาเปนของเหตุการณใดและจดัการกบัเหตุการณนัน้ - throw คือ หากเกิดขอผิดพลาดบางอยาง exception ถูกโยนออกจากโปรแกรม

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

260

รูปแบบการใช Throws กรณีที่ 1 : การเกิด exception(การโยน exception)จาก method

[Modifier] return_type method_name([argumentsล) throws ExceptionType [, ExceptionType,…] { [statements]

throw exception_object [statements]

}

กรณีที่ 2 : หาก exception ไมไดรับการดักจับภายใน method ที่โยน exception นั้นออกมา method ที่เปนผูเรียกเมธอดนั้นใหทํางานจะตองเลือกระหวางการดกัจับ exception หรือ สงตอ exception ใหกบัเมธอดที่เรียกใชงาน อยางใดอยางหนึ่ง ซ่ึงในการสงตอ exception จะตองประกาศ method ดังนี ้

[Modifier] return_type method_name([argumentsล) throws ExceptionType [, ExceptionType,…] { [statements]

} เปนการประกาศวา method นั้นอาจจะโยนออปเจ็ค Exception ประเภทนั้นๆ(ExceptionType)

ออกไป และสามารถมี ExceptionType ไดหลายตวัแตไมซํ้ากัน ตัวอยาง การประกาศ Throws

void method1() throws NullPointerException, IOException { . . .

} คําสั่ง Throws

รูปแบบ throw ExceptionObject;

เปนการสั่งให JVM โยนออปเจ็ค Exception ที่เราระบุออกไปโดยไมไดเกิดขอผิดผลาดใดๆ

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

261

ตัวอยาง การใชคําสั่ง throw if ( x == 0 ) {

throw new ArithmeticException(); } else {

return 5 / x; }

ตัวอยาง การใช throw และ throws รวมกัน

- ตัวอยางนี้เกดิ Compiled Error void method1() {

throw new FileNotFoundException(); } - ที่ถูกตองเปน void method1() throws FileNotFoundException {

throw new FileNotFoundException(); } - หรือที่ถูกตองเปน void method1() throws IOException {

throw new FileNotFoundException(); }

ตัวอยาง การจับ Exception ที่เราสรางขึ้น - ตัวอยางที่ผิด void method1() throws IOException { throw new FileNotFoundException(); } void method2() {

try { method1();

} catch (FileNotFoundException e) { }

}

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

262

- ที่ถูกตองเปน void method2() {

try { method1();

} catch (IOException e) { }

} ผลของการประกาศ throws

- เมื่อนํา Method นั้นไปใชจะตองใชคําสั่ง try…catch คอยดักจับ Exception ในชนดินัน้ๆ - เราสามารถใชชนิดของ Exception ที่มี Hierarchy ที่สูงกวามารับ

ตัวอยางดักจับ Method ที่ประกาศ throws

void method1() throws IOException { throw new FileNotFoundException();

} void method2() {

try { method1();

} catch (IOException e) { System.out.println(“IOException”); }

} ผลลัพธที่ไดคือ

IOException ตัวอยางดักจับ Method ที่ประกาศ throws void method1() throws IOException {

throw new FileNotFoundException(); }

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

263

void method2() { try {

method1(); } catch (FileNotFoundException e) {

Sytem.out.println(“FileNotFoundException”); } catch (IOException e) { System.out.println(“IOException e”); } } ผลลัพธที่ไดคือ

FileNotFoundException ตัวอยาง throw และ throws เมื่อ method 2 เรียกใช method 1 แลว method 1 ได throws exception ทําให method ที่เรียกใชงานตอง thows exception เดียวกนั หรือ ซุปเปอรคลาสของ exception นั้น

- การประกาศ method ที่มีการ throws แลวเกิด ขอผิดพลาด compile error void method1() throws IOException {

throw new FileNotFoundException(); } void method2() {

method1(); }

- ที่ถูกตองเปน void method1() throws IOException {

throw new FileNotFoundException(); } void method2() throws IOException {

method1(); }

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

264

ตัวอยาง การ throws ออกจาก method - ทําการคอมไพลแลวเกิด compile error void method1() { throw new FileNotFoundException(); } - ที่ถูกตองเปน void method1() throws FileNotFoundException {

throw new FileNotFoundException(); } - หรือ ที่ถูกตองเปน void method1() throws IOException {

throw new FileNotFoundException(); }

ตัวอยาง การThrows ออกจาก method class testThrows{

static int div(int x , int y) throws ArithmeticException { return (x/y); } public static void main(String args[]){ try { System.out.println(div(15,0)); } catch (ArithmeticException e){ System.out.println(e.toString()); System.out.println(e.getMessage()); }

}} ผลลัพธที่ไดคือ java.lang.ArithmeticException: / by zero / by zero

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

265

ตัวอยาง การ throw exception ออกจาก method class testThrow1{ static int div(int x, int y){ try{ if(y==0) throw new ArithmeticException(); return x/y; } catch (ArithmeticException e){

return Integer.MAX_VALUE; // 2147483647 } } public static void main(String[] args) { System.out.println(div(1,0)); } } ผลลัพธที่ไดคือ

2147483647 ตัวอยาง class ThrowException{ void method1(double a, double b){ try{ System.out.println(method2(a,b)); } catch(ArithmeticException ex){ System.out.println(ex.getMessage()); } } String method2(double a, double b) throws ArithmeticException{ if (b==0){ System.out.println(a + "/" + b + "==>"); throw new ArithmeticException(); } else return a + "/" + b + "=" + a / b; } public static void main(String args[]){ ThrowException t = new ThrowException();

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

266

t.method1(20.0,3.0); t.method1(20.0,0.0); t.method1(20.0,5.0); }

} ผลลัพธคือ 20.0/3.0=6.666666666666667 20.0/0.0==> null 20.0/5.0=4.0

ตัวอยาง throw และ throws

public class Test { public static void aMethod() throws Exception {

try { throw new Exception(); } finally { System.out.println(“finally”); }

} public static void main(String args[]) {

try { aMethod(); } catch (Exception e) { System.out.println(“exception”);

} System.out.println(“finished”);

} }

ผลลัพธที่ไดคือ finally exception finished

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

267

Exception Classes ของเราเอง เราสามารถที่จะสืบทอด Exception Class ใชเปนชนิดของเราเองได Excection Class ที่เราจะสืบทอดเพื่อนํามาใชควรเปนในตระกลู Exception ไมควรใช Error หรือ RuntimeException

ตัวอยาง การสรางคลาส Exception ใชงานเอง

class MyException extends Exception { } public class Test {

public static void aMethod() throws MyException { throw new MyException();

} public static void main(String args[]) {

try { aMethod();

} catch (MyException e) { System.out.println(“MyException”);

} catch (Exception e) { System.out.println(“Exception”);

} }

} ผลลัพธที่ไดคือ MyException

ตัวอยาง การสรางคลาส Exception ใชงานเอง class MyException extends Exception{ MyException(String s){ super(s); } } public class ExcepScope{ static void sayHello(String s) throws MyException{ if (s.equals("John")) throw new MyException("Bad Guy"); System.out.println("Hello !" + s); }

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

268

public static void main(String args[]){ String n[] = {"Joe" , "Jack" , "John" ,"Jim"}; for(int i = 0 ; i < n.length ; i++){ try{ sayHello(n[i]); } catch (MyException e){ System.out.println("No hello for a bad guy"); } } }}

ผลลัพธที่ไดคือ Hello !Joe Hello !Jack No hello for a bad guy Hello !Jim

บทท่ี 11 การดักจับขอผิดพลาด หนาที่

เอกสารประกอบการสอน 305272 การเขียนโปรแกรมคอมพิวเตอรขั้นสูง อ.สุรางคนา ระวังยศ

269

แบบฝกหัด 1. ใหนิสิตทําการดักจับขอผิดพลาดที่เกิดในโปรแกรมนี ้ public class Error1 { public static void main(String[] args) { int x = 5 / 0; System.out.println("Result = " + x); } } ส่ิงที่ไดขณะ run โปรแกรมคือ Exception in thread "main" java.lang.ArithmeticException: / by zero at Error1.main(Error1.java:3) 2. จากโปรแกรมตอไปนี ้class testFinally1{ public static void main(String args[]){ String input ; input = "Madee" ; // **TEST*** try{ if ((input.equals("Madee"))) return; System.out.println("Hello " + input); } catch (Exception e){ System.out.println("Hello , whoever you are"); } finally { System.out.println("How are you today?"); } System.out.println("It's nice to see you"); } } จากโปแกรม testFinally1 ทําการทดลองเปลี่ยนแปลงคาในบรรทัด //** TEST *** 3 กรณีดังตอไปนี ้

1 . input = null; 2. input = “Joe“ 3. input = "Madee" ; ผลลัพธที่ไดทั้งสามกรณีคืออะไร พรอมทั้งอธิบายเหตุผล