Trong Java, có hai loại chính của exceptions: Checked exceptions và Unchecked exceptions. Mỗi loại có cách xử lý và mục đích riêng trong quá trình lập trình, dựa trên cách ngoại lệ đó có thể dự đoán và kiểm soát được.

1. Checked Exceptions (Ngoại lệ kiểm tra)

Checked exceptions là những ngoại lệ mà trình biên dịch (compiler) yêu cầu lập trình viên phải xử lý. Các ngoại lệ này thường liên quan đến những tình huống có thể dự đoán được nhưng không thể ngăn chặn, chẳng hạn như việc đọc ghi tệp tin, kết nối cơ sở dữ liệu, hoặc gọi các phương thức trong API mà có thể gây lỗi.

Khi một checked exception xảy ra, bạn bắt buộc phải xử lý nó bằng cách sử dụng khối try-catch hoặc khai báo nó trong chữ ký phương thức với từ khóa throws. Nếu không xử lý hoặc không khai báo, chương trình sẽ không biên dịch được.

Ví dụ về checked exceptions:

  • IOException (Ngoại lệ xảy ra khi thao tác với input/output như đọc file)
  • SQLException (Ngoại lệ khi làm việc với cơ sở dữ liệu)
  • FileNotFoundException (Ngoại lệ khi file không được tìm thấy)

Ví dụ:

import java.io.*;

public class CheckedExceptionExample {
    public static void main(String[] args) {
        try {
            FileReader file = new FileReader("non_existent_file.txt"); // Có thể gây ra FileNotFoundException
        } catch (FileNotFoundException e) {
            System.out.println("File không tồn tại: " + e.getMessage());
        }
    }
}

2. Unchecked Exceptions (Ngoại lệ không kiểm tra)

Unchecked exceptions là những ngoại lệ mà trình biên dịch không yêu cầu bắt buộc phải xử lý. Chúng thường là kết quả của các lỗi logic hoặc lập trình không hợp lệ và không yêu cầu bắt buộc người lập trình phải xử lý, nhưng có thể tránh được nếu lập trình viên viết mã cẩn thận.

Các ngoại lệ này được thừa kế từ lớp RuntimeException và có thể xảy ra bất cứ lúc nào trong quá trình chạy chương trình. Mặc dù không bắt buộc phải xử lý các ngoại lệ này, bạn vẫn có thể bắt và xử lý chúng nếu cần.

Ví dụ về unchecked exceptions:

  • NullPointerException (Ngoại lệ khi cố truy cập đối tượng null)
  • ArrayIndexOutOfBoundsException (Ngoại lệ khi truy cập phần tử mảng không tồn tại)
  • ArithmeticException (Ngoại lệ khi phép toán số học không hợp lệ như chia cho 0)

Ví dụ:

public class UncheckedExceptionExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        System.out.println(numbers[5]); // Gây ra ArrayIndexOutOfBoundsException
    }
}

Sự khác biệt giữa Checked và Unchecked Exceptions

  1. Kiểm tra bởi trình biên dịch:
    • Checked exceptions: Trình biên dịch yêu cầu bắt buộc phải xử lý hoặc khai báo ngoại lệ này.
    • Unchecked exceptions: Trình biên dịch không yêu cầu xử lý, chúng xảy ra trong runtime và có thể không cần bắt.
  2. Nguyên nhân:
    • Checked exceptions: Thường liên quan đến các lỗi ngoại vi có thể dự đoán trước được (như I/O, kết nối cơ sở dữ liệu).
    • Unchecked exceptions: Thường là lỗi lập trình như logic sai, tham chiếu đối tượng null, hoặc vượt quá giới hạn mảng.
  3. Cách xử lý:
    • Checked exceptions: Phải được xử lý bằng try-catch hoặc khai báo với throws.
    • Unchecked exceptions: Không bắt buộc phải xử lý, nhưng có thể xử lý nếu muốn.
  4. Thừa kế:
    • Checked exceptions: Kế thừa trực tiếp từ lớp Exception, trừ RuntimeException.
    • Unchecked exceptions: Kế thừa từ RuntimeException.

Tóm lại

Checked exceptions yêu cầu lập trình viên xử lý các tình huống có thể dự đoán trước được, đảm bảo chương trình ổn định trước những lỗi ngoại vi như file không tồn tại. Trong khi đó, unchecked exceptions là những lỗi không được dự đoán dễ dàng và thường là do lỗi lập trình, nhưng trình biên dịch không bắt buộc phải xử lý chúng.