Java คือ ตอนที่ 7 : การจัดการข้อผิดพลาด (Error Handling) และข้อยกเว้น (Exceptions)

  1. ทำความเข้าใจเกี่ยวกับการจัดการข้อผิดพลาด (Error Handling)
  2. แนะนำข้อยกเว้น (Exceptions)
  3. ประเภทของข้อยกเว้น (Types of Exceptions)
  4. การจัดการข้อยกเว้นด้วย Try-Catch-Finally
  5. แอปพลิเคชันในโลกแห่งความเป็นจริง: ทำแอพธนาคารอย่างง่าย

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

1. ทำความเข้าใจเกี่ยวกับการจัดการข้อผิดพลาด (Error Handling)

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

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

2. แนะนำข้อยกเว้น (Exceptions)

ข้อยกเว้นใน Java แสดงถึงเหตุการณ์ที่เกิดขึ้นระหว่างการดำเนินการของโปรแกรมและขัดขวางการไหลตามปกติ คำว่า “exception” หมายถึงเหตุการณ์ที่เป็น “exceptional condition” หมายความว่าเหตุการณ์นี้ไม่ควรเกิดขึ้นภายใต้การทำงานปกติ

ใน Java ข้อยกเว้นถูกจัดการในลักษณะที่มีโครงสร้างโดยใช้โครงสร้างที่จัดเตรียมโดยภาษา เมื่อเหตุการณ์พิเศษเกิดขึ้น วัตถุยกเว้นจะถูกสร้างขึ้นและส่งไปยังเมธอดที่เกิดปัญหา ข้อยกเว้นที่เกิดขึ้นต้องถูกจับและจัดการที่ใดที่หนึ่งในโปรแกรม ถ้าไม่ ตัวจัดการข้อยกเว้นเริ่มต้นของ Java Virtual Machine (JVM) จะจัดการ ซึ่งมักจะส่งผลให้โปรแกรมยุติ

3. ประเภทของข้อยกเว้น (Types of Exceptions)

มีข้อยกเว้นสองประเภทหลักใน Java: ข้อยกเว้นที่ตรวจสอบและข้อยกเว้นที่ไม่ตรวจสอบ

ข้อยกเว้นที่เลือก (Checked exceptions): แสดงถึงเงื่อนไขที่ไม่ถูกต้องในพื้นที่ที่อยู่นอกเหนือการควบคุมของโปรแกรม ซึ่งรวมถึงสถานการณ์ต่างๆ เช่น ไม่พบไฟล์หรือการเชื่อมต่อเครือข่ายล้มเหลว Java กำหนดให้ข้อยกเว้นเหล่านี้ต้องถูกจับและจัดการ หรือประกาศใน throws ส่วนคำสั่งของเมธอด

ข้อยกเว้นที่ไม่ได้ตรวจสอบ (Unchecked exceptions): หรือที่เรียกว่าข้อยกเว้นรันไทม์ แสดงถึงข้อบกพร่องในโปรแกรมที่สามารถป้องกันได้ด้วยการเขียนโค้ดที่เหมาะสม ซึ่งรวมถึงข้อผิดพลาดทางตรรกะ เช่น การหารด้วยศูนย์หรือการเข้าถึงอาร์เรย์นอกขอบเขต ข้อยกเว้นเหล่านี้ไม่จำเป็นต้องประกาศใน throws ส่วนคำสั่งของเมธอด

4. การจัดการข้อยกเว้นด้วย Try-Catch-Finally

Java จัดเตรียมบล็อก try-catch-finally สำหรับการจัดการข้อยกเว้น

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

บล็อก catch ช้เพื่อจัดการกับข้อยกเว้น คุณสามารถระบุประเภทของข้อยกเว้นที่คุณต้องการตรวจจับได้

บล็อก finally ประกอบด้วยข้อความสำคัญทั้งหมดที่ต้องดำเนินการไม่ว่าจะมีการจัดการข้อยกเว้นหรือไม่ก็ตาม

นี่คือตัวอย่างพื้นฐาน:

try {
    // Code that might throw an exception
} catch (ExceptionType name) {
    // Code to handle the exception
} finally {
    // Code to be executed regardless of an exception
}

5. แอปพลิเคชันในโลกแห่งความเป็นจริง: ทำแอพธนาคารอย่างง่าย

ตอนนี้เรามีความเข้าใจเกี่ยวกับการจัดการข้อผิดพลาดและข้อยกเว้นแล้ว เรามาทำแอพธนาคารอย่างง่ายเพื่อแสดงแนวคิดเหล่านี้ในทางปฏิบัติ

แอปพลิเคชันจะมีคุณสมบัติ เช่น สร้างบัญชี ฝากเงิน ถอนเงิน และตรวจสอบยอดเงินในบัญชี เพื่อความง่าย เราจะปรับใช้เป็นแอปพลิเคชันคอนโซล

โครงสร้างแอปพลิเคชัน

เริ่มต้นด้วยการสร้างคลาส BankAccount:

public class BankAccount {
    private double balance;

    public BankAccount() {
        this.balance = 0.0;
    }

    // getters and setters
    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}

การจัดการข้อยกเว้น

คลาส BankAccount จะมีวิธีการฝากและถอนเงิน และการดำเนินการเหล่านี้อาจมีข้อยกเว้น ตัวอย่างเช่น คุณไม่สามารถถอนเงินได้หากมีเงินในบัญชีไม่เพียงพอ

มากำหนดข้อยกเว้นการตรวจสอบที่กำหนดเอง InsufficientFundsException:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

ตอนนี้ เรามาเพิ่มวิธีการในคลาส BankAccount สำหรับการฝากและถอนเงิน:

public class BankAccount {
    //... existing code ...

    public void deposit(double amount) {
        if(amount > 0) {
            balance += amount;
        } else {
            throw new IllegalArgumentException("Deposit amount must be positive.");
        }
    }

    public void withdraw(double amount) throws InsufficientFundsException {
        if(amount > balance) {
            throw new InsufficientFundsException("Insufficient funds. Please enter a lesser amount.");
        } else if(amount <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive.");
        } else {
            balance -= amount;
        }
    }
}

สังเกตวิธีที่เราใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบ ( IllegalArgumentException) สำหรับเงื่อนไขที่ไม่ควรเกิดขึ้นหากโปรแกรมมีการเขียนโค้ดอย่างถูกต้อง และตรวจสอบข้อยกเว้น ( InsufficientFundsException) สำหรับเงื่อนไขที่อาจเกิดขึ้นโดยไม่คำนึงว่าโปรแกรมจะถูกเขียนโค้ดอย่างดีเพียงใด

การโต้ตอบกับผู้ใช้

เราจะใช้คลาส BankApp เพื่อโต้ตอบกับผู้ใช้ คลาสนี้จะสร้างBankAccountวัตถุและใช้เพื่อดำเนินการตามอินพุตของผู้ใช้

แอปพลิเคชันจะมีเมนูข้อความง่ายๆ:

public class BankApp {
    public static void main(String[] args) {
        // Initialize Scanner and BankAccount
        Scanner scanner = new Scanner(System.in);
        BankAccount account = new BankAccount();

        // User menu
        while (true) {
            System.out.println("1. Deposit money");
            System.out.println("2. Withdraw money");
            System.out.println("3. Check balance");
            System.out.println("4. Exit");
            System.out.print("Choose an option: ");
            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    System.out.print("Enter the amount to deposit: ");
                    double depositAmount = scanner.nextDouble();
                    try {
                        account.deposit(depositAmount);
                        System.out.println("Successfully deposited " + depositAmount);
                    } catch (IllegalArgumentException e) {
                        System.out.println("Error: " + e.getMessage());
                    }
                    break;
                case 2:
                    System.out.print("Enter the amount to withdraw: ");
                    double withdrawAmount = scanner.nextDouble();
                    try {
                        account.withdraw(withdrawAmount);
                        System.out.println("Successfully withdrew " + withdrawAmount);
                    } catch (InsufficientFundsException | IllegalArgumentException e) {
                        System.out.println("Error: " + e.getMessage());
                    }
                    break;
                case 3:
                    System.out.println("Current balance: " + account.getBalance());
                    break;
                case 4:
                    scanner.close();
                    System.exit(0);
            }
        }
    }
}

ในคลาส BankApp เราใช้บล็อก try-catch เพื่อจัดการข้อยกเว้นที่ส่งโดยเมธอด depositandwithdraw


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

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

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

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

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


Java คืออะไร

Java คือ ตอนที่ 6 : Packages และ Access Modifiers
Java คือ ตอนที่ 8 : โครงสร้างข้อมูล (Data Structures)