Chapter 11. Exceptions
Focus on improving, not proving.
📌 1. Tổng quan về Exception Handling
Trong Java, ngoại lệ (Exception) là một sự kiện xảy ra trong quá trình thực thi chương trình làm gián đoạn luồng thực thi bình thường. Java cung cấp cơ chế để bắt (catch), xử lý (handle) và khôi phục (recover) từ lỗi thông qua hệ thống try-catch-finally.
🔹 Có hai loại lỗi chính trong Java:
Loại lỗi
Mô tả
Error
Những lỗi nghiêm trọng không thể khắc phục được như OutOfMemoryError, StackOverflowError.
Exception
Những lỗi có thể xử lý được như NullPointerException, IOException, ArithmeticException.
📌 Ví dụ về lỗi không thể xử lý (Error
):
public class TestError {
public static void main(String[] args) {
main(args); // Gọi đệ quy vô hạn → StackOverflowError
}
}
📌 Ví dụ về lỗi có thể xử lý (Exception
):
public class TestException {
public static void main(String[] args) {
int a = 5 / 0; // ArithmeticException
}
}
📌 2. Exception Hierarchy (Phân cấp ngoại lệ trong Java)
Tất cả các ngoại lệ trong Java đều kế thừa từ Throwable
.
Throwable
/ \
Error Exception
/ \
RuntimeException IOException (và các loại khác)
✅ Error
: Lỗi nghiêm trọng (không bắt được).
✅ Exception
: Lỗi có thể xử lý được.
✅ RuntimeException
: Ngoại lệ xảy ra trong runtime (Unchecked Exception).
🔹 Checked vs Unchecked Exceptions
Loại
Mô tả
Ví dụ
Checked Exception
Bắt buộc phải xử lý (compile-time)
IOException, SQLException
Unchecked Exception
Không bắt buộc xử lý (runtime)
NullPointerException, ArithmeticException
📌 Ví dụ về Checked Exception (phải xử lý):
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
FileReader fr = new FileReader(new File("file.txt"));
} catch (IOException e) {
System.out.println("File not found!");
}
}
}
📌 Ví dụ về Unchecked Exception (không bắt buộc xử lý):
public class UncheckedExceptionExample {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[5]); // ArrayIndexOutOfBoundsException
}
}
📌 3. Cơ chế Try-Catch-Finally
Java cung cấp 3 khối chính để xử lý ngoại lệ:
🔹 try-catch
Cú pháp:
try {
// Code có thể gây lỗi
} catch (ExceptionType e) {
// Xử lý lỗi
}
📌 Ví dụ:
public class TryCatchExample {
public static void main(String[] args) {
try {
int a = 5 / 0;
} catch (ArithmeticException e) {
System.out.println("Lỗi chia cho 0");
}
}
}
🔹 finally
finally
luôn chạy dù có ngoại lệ hay không.
📌 Ví dụ:
public class FinallyExample {
public static void main(String[] args) {
try {
int a = 5 / 0;
} catch (ArithmeticException e) {
System.out.println("Lỗi chia cho 0");
} finally {
System.out.println("Luôn chạy finally");
}
}
}
🔹 try-with-resources
Dùng cho AutoCloseable
như FileReader
, BufferedReader
.
📌 Ví dụ:
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (FileReader fr = new FileReader("file.txt")) {
// Đọc file
} catch (IOException e) {
System.out.println("Lỗi đọc file");
}
}
}
📌 4. Tạo Custom Exception
Chúng ta có thể tạo ngoại lệ riêng bằng cách kế thừa Exception
hoặc RuntimeException
.
📌 Ví dụ:
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void main(String[] args) throws MyException {
throw new MyException("Lỗi tùy chỉnh!");
}
}
**📌 5. Throw vs Throws
Từ khóa
Mô tả
throw
Ném một ngoại lệ cụ thể trong code
throws
Khai báo phương thức có thể ném ngoại lệ
📌 Ví dụ về throw
:
public class ThrowExample {
public static void main(String[] args) {
throw new ArithmeticException("Lỗi chia cho 0");
}
}
📌 Ví dụ về throws
:
public class ThrowsExample {
public static void method() throws IOException {
throw new IOException("Lỗi đọc file");
}
}
📌 6. Chặn Exception trong kế thừa
Nếu một phương thức throws
một ngoại lệ, phương thức override có thể:
Không khai báo ngoại lệ
Khai báo cùng ngoại lệ
Khai báo ngoại lệ con
📌 Ví dụ hợp lệ:
class Parent {
void show() throws IOException {}
}
class Child extends Parent {
void show() throws FileNotFoundException {} // OK (FileNotFoundException là con của IOException)
}
📌 Ví dụ không hợp lệ:
class Parent {
void show() throws IOException {}
}
class Child extends Parent {
void show() throws Exception {} // LỖI: Exception rộng hơn IOException
}
📌 7. Lưu ý quan trọng
✅ Luôn dùng try-with-resources
để tránh rò rỉ tài nguyên.
✅ Không nên catch Exception chung chung (catch (Exception e)
) trừ khi thật cần thiết.
✅ Chỉ bắt những ngoại lệ mà bạn có thể xử lý.
✅ Ghi log ngoại lệ để dễ debug.
📌 Ví dụ log lỗi đúng cách:
import java.util.logging.Level;
import java.util.logging.Logger;
public class LoggingExample {
private static final Logger LOGGER = Logger.getLogger(LoggingExample.class.getName());
public static void main(String[] args) {
try {
int a = 5 / 0;
} catch (ArithmeticException e) {
LOGGER.log(Level.SEVERE, "Lỗi chia cho 0", e);
}
}
}
📌 8. Tổng kết
✅ Exception là lỗi có thể xử lý, Error là lỗi không thể khắc phục. ✅ Có Checked Exception (phải xử lý) và Unchecked Exception (không bắt buộc xử lý). ✅ Cơ chế xử lý: try-catch-finally, throw, throws. ✅ Có thể tạo Custom Exception. ✅ Dùng try-with-resources để tránh rò rỉ tài nguyên.
Last updated