การจัดการกับความผิดปกติ เขียนโปรแกรม Java เบื้องต้น
หัวข้อ ความผิดพลาด ความผิดปกติ การจัดการกับความผิดปกติ การแจ้งว่าเกิดความผิดปกติ
ความผิดพลาด
ความผิดพลาด Syntax Error Logical Error เขียนขึ้นผิดจากข้อกำหนดในภาษานั้น สามารถตรวจพบได้ง่าย ตั้งแต่ตอนคอมไพล์โปรแกรม Logical Error เกิดจากความเข้าใจผิดของตัวผู้เขียนโปรแกรมเอง ความผิดพลาดลักษณะนี้จะตรวจพบได้ยาก เนื่องจากตัวภาษาจะไม่แจ้งความผิดพลาดนั้นออกมา
Syntax Error public class SyntaxError { public static void main(String[] args) { int i; System.out.println(i); }
คอมไพล์ไม่ผ่าน
Logical Error public class LogicalError { public static void main(String[] args) { int i = 2000000000; System.out.println(i*2); } -294967296
ความผิดปกติ
ปัจจัยที่ไม่สามารถควบคุมได้ หน่วยความจำที่มีจำกัด อุปกรณ์การรับและส่งข้อมูลที่อาจขัดข้อง การกรอกข้อมูลที่ผิดพลาด
ตัวอย่างโปรแกรมที่เกิดความผิดปกติ public class ExceptionError { public static void main(String[] args) { int[] array = new int[3]; System.out.println(array[3]); }
ตัวอย่างโปรแกรมที่อาจจะเกิดความผิดปกติ public class ExceptionError { public static void main(String[] args) { String name = args[0]; System.out.println("Hello " + name); }
ความผิดปกติขณะทำงาน
การจัดการความผิดปกติในภาษา C ตรวจสอบค่าที่ส่งคืน FILE *fp; fp = fopen(“mypic.jpg”, “r”); if (fp == NULL) { printf(“Cannot Open Image\n”); exit(0); }
ข้อเสีย อาจละเลยการตรวจสอบได้ ภาษา C ไม่ได้บังคับว่าจะต้องมีการตรวจสอบความผิดปกติเช่นนี้ทุกครั้ง โปรแกรมเมอร์ต้องตรวจสอบเอง คำสั่งหลักอยู่ปนกับคำสั่งจัดการความผิดปกติ ใช้ if เพื่อดักจับความผิดปกติทุกครั้ง ไม่สามารถระบุสาเหตุของความผิดปกติ ค่าที่คืนอาจเป็น NULL หรือตัวเลขติดลบ ไม่เพียงพอที่จะอธิบายถึงสาเหตุหลักของความผิดปกติได้
การจัดการความผิดปกติในภาษา Visual Basic มีส่วนที่ใช้จัดการความผิดปกติ On Error GoTo LoadPicError MyImage.Picture = LoadPicture(“mypic.jpg”) Exit Sub LoadPicError: MsgBox(Err.Description)
ข้อเสีย ตรวจสอบลำดับการทำงานตรวจสอบลำดับการทำงานได้ยาก การใช้คำสั่ง GoTo เพื่อให้โปรแกรมข้ามการทำงานไปยังบริเวณที่จัดการความผิดปกติ ทำให้โครงสร้างของโปรแกรมไม่เป็นระเบียบ มีทางออกจากฟังก์ชันได้หลายทาง จัดการความผิดปกติได้ยาก การจัดการความผิดปกติจะต้องระบุอยู่เฉพาะในฟังก์ชันนั้นๆ เท่านั้น ไม่สามารถส่งให้ผู้เรียกใช้ฟังก์ชันนั้นตัดสินใจได้เองว่าจะจัดการกับความผิดปกติอย่างไร
การจัดการความผิดปกติในภาษา Java รูปแบบ try { ประโยคทำงานที่อาจเกิดความผิดปกติ; } catch (วัตถุException) { ประโยคที่ใช้จัดการความผิดปกติ; try catch
ไม่จัดการความผิดปกติ import java.util.Scanner; public class NoTryCatch { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str = sc.next(); int i = Integer.parseInt(str); System.out.println(i); }
ผลการทำงาน เมื่อป้อนค่า 10 เมื่อป้อนค่า 10.5 10 Exception in thread "main" java.lang.NumberFormatException: For input string: "10.5" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:456) at java.lang.Integer.parseInt(Integer.java:497) at NoTryCatch.main(NoTryCatch.java:8)
จัดการความผิดปกติด้วย try-catch Scanner sc = new Scanner(System.in); String str = sc.next(); int i = 0; try { i = Integer.parseInt(str); } catch (Exception e) { System.out.println("Catch exception"); } System.out.println(i);
ผลการทำงาน เมื่อป้อนค่า 10 10 เมื่อป้อนค่า 10.5 Catch exception
การจัดการความผิดปกติตามชนิด รูปแบบ try { ประโยคทำงานที่อาจเกิดความผิดปกติ; } catch (วัตถุ Exception ชนิดที่ 1) { ประโยคที่ใช้จัดการความผิดปกติชนิดที่ 1; catch (วัตถุ Exception ชนิดที่ 2) { ประโยคที่ใช้จัดการความผิดปกติชนิดที่ 2; try catch catch
การจัดการความผิดปกติตามชนิด try { i = Integer.parseInt(str); } catch (NumberFormatException e) { System.out.println("Catch number format exception"); } catch (Exception e) { System.out.println("Catch exception"); } System.out.println(i);
ผลการทำงาน เมื่อป้อนค่า 10 เมื่อป้อนค่า 10.5 10 Catch number format exception
finally รูปแบบ try { ประโยคสำหรับจองทรัพยากร; ประโยคทำงานที่อาจเกิดความผิดปกติ; } catch (วัตถุ Exception) { ประโยคที่ใช้จัดการความผิดปกติ; finally { ประโยคสำหรับการคืนทรัพยากร; try catch finally
เหตุการณ์ปรกติ int[] array = {10,20,30}; int count = array.length; java.io.PrintWriter writer = null; try{ writer = new java.io.PrintWriter("c:\\Temp\\test.txt"); for( int i = 0; i < count; i++) writer.println(array[i]); }
เปิดไฟล์ไม่ได้ int[] array = {10,20,30}; int count = array.length; java.io.PrintWriter writer = null; try{ writer = new java.io.PrintWriter("c:\\TTTT\\test.txt"); for( int i = 0; i < count; i++) writer.println(array[i]); }
อ้างเกินขอบเขต int[] array = {10,20,30}; int count = array.length + 1; java.io.PrintWriter writer = null; try{ writer = new java.io.PrintWriter("c:\\Temp\\test.txt"); for( int i = 0; i < count; i++) writer.println(array[i]); }
โค้ดซ้ำซ้อน int[] array = {10,20,30}; int count = array.length; java.io.PrintWriter writer = null; try{ writer = new java.io.PrintWriter("c:\\Temp\\test.txt"); for( int i = 0; i < count; i++) writer.println(array[i]); if( writer == null) System.out.println("Cannot open file for write!"); else writer.close(); }
โค้ดซ้ำซ้อน catch(IndexOutOfBoundsException e) { System.out.print("Catch index out of bounds exception "); System.out.println(e); if( writer == null) System.out.println("Cannot open file for write!"); else writer.close(); } catch(IOException e) { System.out.print("Catch io exception ");
ใช้ finally เพื่อกำจัดโค้ดซ้ำซ้อน int[] array = {10,20,30}; int count = array.length; java.io.PrintWriter writer = null; try{ writer = new java.io.PrintWriter("c:\\Temp\\test.txt"); for( int i = 0; i < count; i++) writer.println(array[i]); }
ใช้ finally เพื่อกำจัดโค้ดซ้ำซ้อน catch(IndexOutOfBoundsException e) { System.out.print("Catch index out of bounds exception "); System.out.println(e); } catch(IOException e) { System.out.print("Catch io exception "); finally{ if( writer == null) { System.out.println("Cannot open file for write!"); else { writer.close();
ประเภทของความผิดปกติ
ประเภทของความผิดปกติ ไม่ต้องตรวจสอบ ต้องตรวจสอบ ต้องอยู่ใน try-catch
ความผิดปกติที่ไม่ต้องตรวจสอบ ไม่ต้องตรวจเพราะส่วนใหญ่เกิดจากความผิดพลาดในการเขียนโปรแกรม เช่น NumberFormatException IndexOutOfBoundsException NullPointerException IllegalArgumentException มี RuntimeException เป็นคลาสแม่
ความผิดปกติที่ต้องตรวจสอบ ต้องตรวจเพราะอาจจะเกิดความผิดปกติเมื่อนำโปรแกรมไปรัน ต้องอยู่ใน try-catch เสมอ เช่น IOException FileNotFoundException
การแจ้งว่าเกิดความผิดปกติ
การแจ้งว่าเกิดความผิดปกติ รูปแบบ throw วัตถุ_exception; ตัวอย่าง Exception e = new Exception("Negative Number"); if (i < 0) throw e; หรือ throw new Exception("Negative Number");
การแจ้งว่าเกิดความผิดปกติ try { i = Integer.parseInt(str); if (i < 0) { throw new Exception(); } } catch (NumberFormatException e) { System.out.println("Catch number format exception"); } catch (Exception e) { System.out.println("Catch exception");
ผลการทำงาน เมื่อป้อนค่า 10 เมื่อป้อนค่า 10.5 เมื่อป้อนค่า -10 10 Catch number format exception เมื่อป้อนค่า -10 Catch exception -10
สรุป
สรุป การจัดการความผิดปกติเป็นการแก้ไขความผิดพลาดต่าง ๆ ที่เกิดจากปัจจัยภายนอกซึ่งไม่สามารถควบคุมได้ โปรแกรมภาษา C ต้องตรวจสอบความผิดปกติเองทุกครั้ง โปรแกรมภาษา Visual Basic ถึงแม้จะสามารถแยกส่วนการจัดการความผิดปกติออกจากส่วนของโปรแกรมหลัก โปรแกรมภาษา Java มีรูปแบบการจัดการความผิดปกติด้วย try-catch-finally block
สรุป คำสั่งที่อาจเกิดความผิดปกติจะไว้ในส่วนของ try คำสั่งที่จัดการความผิดปกติจะไว้ในส่วนของ catch การดักจับความผิดปกติด้วย catch นั้น สามารถดักจับแยกตามชนิดของความผิดปกติได้ ส่วนของ finally จะถูกเรียกใช้ทุกครั้งไม่ว่าจะเกิดหรือไม่เกิดความผิดปกติ โดยปกติจะบรรจุเขียนคำสั่งที่คืนทรัพยากร คำสั่ง throws มีไว้เพื่อโยนความผิดปกติที่เกิดขึ้นไปให้กับผู้ที่เรียกใช้เมธอดนี้ ทำให้มีทางเลือกในการจัดการกับความผิดปกติมากขึ้น