VieTopik
Tiếng HànTiếng Anh.NET (C#)Java
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
Java CoreCông cụ hằng ngày
Bài 18/19
5 phút

Exception

Nội dung bài · 6 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Tự ném exception
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt

Người dùng gõ "abc" vào ô số lượng, file cấu hình bị xoá, mạng rớt giữa chừng. Những lỗi này chỉ xuất hiện lúc chạy. Không xử lý thì chương trình dừng ngay. Bài này hướng dẫn cách bắt lỗi và cách tự báo lỗi.

Khái niệm

💥 Exception: object mô tả một lỗi xảy ra lúc chạy, làm chương trình dừng nếu không ai bắt.

🧯 try/catch: cặp khối chạy code trong try, và nếu có exception thì xử lý nó trong catch.

🚨 throw: câu lệnh ném ra một exception, thường viết kèm new để tạo exception đó.

Ví dụ

// Main.java
void main() {
    String input = "abc";

    try {
        int quantity = Integer.parseInt(input);
        System.out.println("Số lượng: " + quantity);
    } catch (NumberFormatException e) {
        System.out.println("Vui lòng nhập một con số");
    }
}
  • Integer.parseInt("abc") ném NumberFormatException. Code còn lại trong try bị bỏ qua, chương trình nhảy sang catch.
  • catch (NumberFormatException e) chỉ bắt đúng loại lỗi đó, và đặt tên e cho exception bắt được. Loại khác vẫn làm chương trình dừng.
  • Có thể thêm khối finally sau catch. Code trong finally luôn chạy, dù có lỗi hay không.
Không Có Chạy code trong try Có exception? Chạy hết try Bỏ phần còn lại, nhảy vào catch finally
Đường chạy của try, catch và finally

Tên exception hay gặp: NumberFormatException (sai định dạng số), NullPointerException (dùng biến đang là null), IllegalArgumentException (tham số không hợp lệ), IllegalStateException (thao tác không hợp lệ lúc đó).

Các exception trên không bắt buộc phải catch. Riêng một số loại như IOException (lỗi đọc ghi file) là checked exception: nơi gọi phải catch hoặc ghi throws IOException ở khai báo method, nếu không sẽ lỗi compile.

Tự ném exception

Khi method nhận dữ liệu không hợp lệ, hãy throw để báo ngay thay vì âm thầm chạy sai:

// Main.java
void main() {
    System.out.println(total(5000, 2));   // 10000
}

long total(long price, int quantity) {
    if (quantity <= 0) {
        throw new IllegalArgumentException(
            "Số lượng phải lớn hơn 0");
    }
    return price * quantity;
}

Thử ngay

Chép chương trình ở trên vào Main.java, thay dòng gọi total trong main bằng:

try {
    System.out.println("A");
    System.out.println(total(5000, 0));
    System.out.println("B");
} catch (IllegalArgumentException e) {
    System.out.println("Lỗi: " + e.getMessage());
} finally {
    System.out.println("C");
}

Đoán trước khi chạy: chữ "B" có được in không?

Xem kết quả
A
Lỗi: Số lượng phải lớn hơn 0
C

"B" không được in. Exception xảy ra ở dòng giữa, nên phần còn lại của try bị bỏ qua.

e.getMessage() là nội dung đã truyền lúc throw. finally vẫn chạy.

Lỗi hay gặp

catch rỗng. Lỗi bị nuốt mất, chương trình chạy sai mà không ai biết.

// SAI — lỗi xảy ra nhưng không ai hay
try {
    int quantity = Integer.parseInt("abc");
} catch (Exception e) {
}
// ĐÚNG — ít nhất phải báo cho người dùng
try {
    int quantity = Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Số lượng không hợp lệ");
}

Bắt Exception trước loại cụ thể. Exception bắt được mọi lỗi, nên catch đứng sau nó không bao giờ chạy tới.

// SAI — lỗi compile: catch thứ hai không bao giờ chạy
try {
    Integer.parseInt("abc");
} catch (Exception e) {
    System.out.println("Có lỗi");
} catch (NumberFormatException e) {
    System.out.println("Sai định dạng");
}
// ĐÚNG — loại cụ thể đứng trước
try {
    Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Sai định dạng");
} catch (Exception e) {
    System.out.println("Có lỗi");
}

Tóm tắt

  • Exception là lỗi lúc chạy, không bắt thì chương trình dừng.
  • try chứa code có thể lỗi, catch xử lý lỗi, finally luôn chạy.
  • Bắt đúng loại exception cụ thể và đặt nó trước Exception. Không để catch rỗng.
  • Dùng throw khi dữ liệu không hợp lệ, đừng âm thầm chạy tiếp.
  • Checked exception như IOException phải được catch hoặc ghi throws, nếu không sẽ lỗi compile.

Tự kiểm tra

0/3 câu
Câu 1

Trong try, Integer.parseInt("abc") ném NumberFormatException. Sau try chỉ có catch (IllegalStateException e). Chuyện gì xảy ra?

Câu 2

Method setPrice(long price) nhận giá âm. Cách xử lý nào hợp lý nhất?

Câu 3

Khối nào luôn chạy, dù try có lỗi hay không?

Stream cơ bảnCompletableFuture cơ bản

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Tự ném exception
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt