Exception

7 September 2016

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับ exception ในภาษา Java มันเป็นวิธีการจัดการข้อผิดพลาดที่เกิดขึ้นในขณะที่โปรแกรมทำงาน

Exception คืออะไร

Exception คือการที่โปรแกรมพยายามจะทำงานบางอย่าง แต่เกิดข้อผิดพลาดขึ้น แล้วโปรแกรมไม่สามารถจัดการข้อผิดพลาดนั้นได้ ซึ่งทำให้เกิด exception ขึ้น และส่งผลทำให้โปรแกรมหยุดทำงาน

Exception เกิดขึ้นในขณะที่โปรแกรมทำงาน ยกตัวอย่างเช่น โปรแกรมกำลังจะเปิดไฟล์ขึ้นมา แต่ไฟล์ที่ต้องการไม่มีอยู่ เป็นต้น รูปแบบการใช้ exception ในภาษา Java เป็นดังนี้

try {
    // try to do something
} catch (Exception1 ex1) {
    // handle for exception 1
}

...

} catch (ExceptionN exN) {
    // handle for exception N
} finally {
    // Always proceed this block whether
    // an exception is thrown or not
}

ในบล็อคคำสั่งของ try เป็นส่วนของโปรแกรมที่อาจจะทำให้เกิด exception ขึ้น และในแต่ละ catch บล็อคเป็นการจัดการกับ exception แต่ละแบบ และบล็อค finally โปรแกรมจะเข้ามาทำงานเสมอไม่ว่าจะเกิด exception ในบล็อคของคำสั่ง try หรือไม่ก็ตาม

ในภาษา Java นั้นมีไลบรารี่มาตรฐานของ exception ที่สามารถให้เราจัดการกับข้อผิดพลาดประเภทต่างๆ ได้ ซึ่ง extend มาจากคลาส Exception สำหรับในบทเรียนนี้ เราจะยกตัวอย่างการใช้ในบางส่วนเท่านั้น

import java.util.Scanner;
public class TestException1 {
    public static void main (String[] args) {
        Scanner reader = new Scanner(System.in);
        int x;

        System.out.print("Enter number: ");
        x = reader.nextInt();
        System.out.println("Your number is " + x);
    }
}

ข้างบนเป็นตัวอย่างของโปรแกรมที่สามารถทำให้เกิด exception ได้ จากคำสั่ง

x = reader.nextInt();

เพราะว่าเมธอด reader.nextInt() นั้นใช้สำหรับอ่านค่าตัวเลข ในการใส่ข้อมูลเข้ามา มันเป็นไปได้ที่ผู้ใช้จะใส่อย่างอื่นที่ไม่ใช่ตัวเลข เช่น ข้อความ ซึ่งจะทำให้เกิด InputMismatchException ขึ้น

การใช้คำสั่ง try catch เพื่อจัดการ exception

เพื่อจัดการและเตรียมรับมือกับ exception ที่อาจจะเกิดขึ้น เราใช้คำสั่ง try เป็นบล็อคสำหรับสิ่งที่พยายามจะทำ และคำสั่ง catch ในการตรวจจับ exception ที่จะเกิดขึ้นและจัดการกับมัน จากตัวอย่างด้านบน เราได้ปรับปรุงโปรแกรมให้สามารถจัดการกับ exception ได้

import java.util.InputMismatchException;
import java.util.Scanner;
public class TestException1 {
    public static void main (String[] args) {
        Scanner reader = new Scanner(System.in);
        int x;

        try {
            System.out.print("Enter number: ");
            x = reader.nextInt();         
            System.out.println("Your number is " + x);
        } catch (InputMismatchException ex) {
            System.out.println("Exception occurred: " + ex);
        }
    }
}

ในตัวอย่าง เราได้ใช้คำสั่ง try ภายในบล็อคของคำสั่งเป็นส่วนของโปรแกรมที่จะทำให้เกิด exception ในบล็อคของคำสั่ง catch เราได้ทำการตรวจจับ exception InputMismatchException ถ้ามันเกิดขึ้น ในบล็อคของคำสั่ง try จะทำการ throw (การโยน) exception มายังบล็อคนี้

System.out.println("Exception occurred: " + ex);

และเราแสดงผลรายละเอียดของออบเจ็คจากคำสั่งข้างบน

Enter number: ab
Exception occurred: java.util.InputMismatchException

และนี่เป็นผลลัพธ์ของโปรแกรม เมื่อเรากรอกค่าที่ไม่ใช่ตัวเลข เราได้ทำการจัดการกับ exception โดยการบอกผู้ใช้ว่าเกิด exception ขึ้นทำให้โปรแกรมไม่หยุดทำงาน และสามารทำงานอย่างอื่นต่อไปได้

ต่อไปมาดูตัวอย่างเพิ่มเติมกับการใช้ exception ที่ซ้อนกัน

import java.util.InputMismatchException;
import java.util.Scanner;

public class TestException1 {
    public static void main (String[] args) {
        Scanner reader = new Scanner(System.in);
        int index;
        int[] array = { 10, 20, 30, 40, 50 };

        try {
            System.out.print("Enter index: ");
            index = reader.nextInt();

            try {
                System.out.println("array[" + index + "] = " + array[index]);
            } catch (IndexOutOfBoundsException ex) {
                System.out.println("Exception occured: " + ex);
                System.out.println("You entered number exceeds the array size");
            }

        } catch (InputMismatchException ex) {
            System.out.println("Exception occurred: " + ex);
            System.out.println("You must specify an index in integer");
        } 
    }
}

ในตัวอย่าง มีสองสิ่งที่อาจจะเกิดขึ้นได้ นั่นคือการใส่ค่าตัวเลขที่ไม่ถูกต้อง และ index ของอาเรย์ไม่ถูกต้องเราได้ทำการ catch exception เหล่านั้น เพื่อไม่ให้โปรแกรมของเราเกิดข้อผิดพลาด คุณจะเห็นว่าคำสั่ง try catch สามารถซ้อนกันได้เหมือนบล็อคคำสั่งอื่นๆ

Enter index: 10
Exception occurred: java.lang.ArrayIndexOutOfBoundsException: 10
You entered number exceeds the array size

และนี่เป็นผลลัพธ์ของโปรแกรมเมื่อเราใส่ตัวเลข 10 ถึงแม้ใน catch การตรวจจับรูปแบบตัวเลขนั้นจะผ่าน แต่เราก็ยังตรวจจับการทำงานในกรณีที่ index เกินขนาดของอาเรย์ด้วย ซึ่งในตัวอย่าง index ของอาเรย์ที่ถูกต้องจะอยุ่ที่ 0 - 4 จึงจะไม่เกิด exception

การใช้คำสั่ง Finally

ในบล็อคของคำสั่ง finally นั้นจะประมวลผลเสมอ ไม่ว่าจะเกิด exception หรือไม่ มันใช้สำหรับการทำงานที่สำคัญ เช่น การปิดไฟล์ หรือปิดการเชื่อมต่อของ stream ต่อไปมาดูตัวอย่างการใช้บล็อคคำสั่ง finally ในภาษา Java โดยเราจะใช้อ่าน text ไฟล์

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class TestFileException {
    public static void main(String[] args) {
        File file = new File("file.txt");
        BufferedReader reader = null;

        try {
            reader = new BufferedReader(new FileReader(file));
            String text = null;

            while ((text = reader.readLine()) != null) {
                System.out.println(text);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
            }
        }
    }
}

ในตัวอย่างข้างบน โปรแกรมจะทำการเปิดfile file.txt เพื่ออ่านค่าและแสดงผลออกทางหน้าจอ เราได้ทำการตรวจจับ FileNotFoundException exception ในกรณีที่ไม่พบไฟล์ หรือในกรณีที่พบแต่ในขณะอ่านเกิดความผิดพลาดขึ้นทำให้เกิด IOException ไม่ว่าโปรแกรมจะเปิดไฟลฺ์สำเร็จแล้ว และอ่านค่าได้หรือไม่ได้ โปรแกรมก็จำเป็นต้องทำการปิดไฟล์นั้น ซึ่งในบล็อคคำสั่ง finally เพื่อปิดไฟล์ดังกล่าว

Info: ในตัวอย่าง คุณต้องสร้างไฟล์ file.txt ใน project directory root เพื่อทำงานกับโปรแกรม

Info: e.printStackTrace(); เป็นเมธอดที่ใช้สำหรับ IDE ในการบอกรายละเอียดเกี่ยวกับข้อผิดพลาดให้กับเรา เช่น บรรทัดที่ทำให้เกิดความผิดพลาด และคลาสที่รัน ใช้สำหรับการ debug โปรแกรม

คลาส Exception

เนืองจากคลาส exception ประเภทต่างๆ ในภาษา Java นั้นสืบทอดมาจากคลาส Exception ดังนั้นคุณสามารถใช้คำสั่ง catch ในการดักจับ exception ทั้งหมดได้

...
catch (Exception e) {
    System.out.println("Exception type: " + e);
}

ยังมี exception ประเภทอื่นอีกที่อาจจะเกิดขึ้น นี่เป็นรายการ exception ทั้งหมดในภาษา Java https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ exception ในภาษา Java และการจัดการกับ exception เหล่านั้นเมื่อมันเกิดขึ้น

บทความนี้เป็นประโยชน์หรือไม่?Yes·No