Throw và Throws trong Java 🎯
🎯 Mục tiêu: Học cách sử dụng throw và throws để quản lý và xử lý ngoại lệ trong Java một cách hiệu quả.
Giới thiệu 📝
Throw và throws là hai từ khóa quan trọng trong xử lý ngoại lệ của Java. Throw được sử dụng để ném ra một ngoại lệ, trong khi throws được sử dụng để khai báo các ngoại lệ có thể xảy ra trong một phương thức.
💡 Fun Fact: Throw và throws giúp chúng ta kiểm soát luồng xử lý lỗi trong chương trình, giúp code dễ bảo trì và an toàn hơn.
1. Throw ⚡
Ném Ngoại Lệ Đơn Giản
public class ThrowExample {
public static void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Tuổi không thể âm");
}
}
}
Ném Ngoại Lệ với Thông Tin Chi Tiết
public class CustomThrow {
public static void validatePassword(String password) {
if (password == null || password.isEmpty()) {
throw new IllegalArgumentException("Mật khẩu không được để trống");
}
if (password.length() < 6) {
throw new IllegalArgumentException("Mật khẩu phải có ít nhất 6 ký tự");
}
}
}
Ném Ngoại Lệ Tùy Chỉnh
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class ThrowCustomException {
public static void processData(String data) {
if (data == null) {
throw new CustomException("Dữ liệu không được null");
}
}
}
2. Throws 🔄
Khai Báo Ngoại Lệ Đơn Giản
public class ThrowsExample {
public static void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
// Đọc file
reader.close();
}
}
Khai Báo Nhiều Ngoại Lệ
public class MultipleThrows {
public static void processFile(String path)
throws FileNotFoundException, IOException {
FileReader reader = new FileReader(path);
// Xử lý file
reader.close();
}
}
Kết Hợp Throw và Throws
public class ThrowAndThrows {
public static void validateAndProcess(String data)
throws CustomException {
if (data == null) {
throw new CustomException("Dữ liệu không hợp lệ");
}
// Xử lý dữ liệu
}
}
3. Ngoại Lệ Tùy Chỉnh 🎨
Tạo Ngoại Lệ Tùy Chỉnh
public class BusinessException extends Exception {
private String errorCode;
public BusinessException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
public String getErrorCode() {
return errorCode;
}
}
Sử Dụng Ngoại Lệ Tùy Chỉnh
public class CustomExceptionExample {
public static void processOrder(String orderId)
throws BusinessException {
if (orderId == null || orderId.isEmpty()) {
throw new BusinessException(
"Mã đơn hàng không hợp lệ",
"INV_001"
);
}
// Xử lý đơn hàng
}
}
4. Ví Dụ Thực Tế 🚀
Xử Lý Đăng Ký Người Dùng
public class UserRegistration {
public static void registerUser(String username, String password)
throws ValidationException {
// Kiểm tra username
if (username == null || username.length() < 3) {
throw new ValidationException(
"Username không hợp lệ",
"username",
username
);
}
// Kiểm tra password
if (password == null || password.length() < 6) {
throw new ValidationException(
"Password không hợp lệ",
"password",
"***"
);
}
// Tiếp tục xử lý đăng ký
}
}
Xử Lý Thanh Toán
public class PaymentProcessor {
public static void processPayment(String transactionId, double amount)
throws PaymentException {
// Kiểm tra số tiền
if (amount <= 0) {
throw new PaymentException(
"Số tiền không hợp lệ",
transactionId,
amount
);
}
// Kiểm tra giới hạn
if (amount > 1000000) {
throw new PaymentException(
"Số tiền vượt quá giới hạn",
transactionId,
amount
);
}
// Tiếp tục xử lý thanh toán
}
}
Xử Lý API Request
public class ApiRequestHandler {
public static void validateRequest(String apiKey, String endpoint)
throws ApiException {
// Kiểm tra API key
if (apiKey == null || apiKey.isEmpty()) {
throw new ApiException(
"API key không hợp lệ",
"AUTH_001",
"API key không được để trống"
);
}
// Kiểm tra endpoint
if (endpoint == null || !endpoint.startsWith("/api/")) {
throw new ApiException(
"Endpoint không hợp lệ",
"URL_001",
"Endpoint phải bắt đầu bằng /api/"
);
}
// Tiếp tục xử lý request
}
}
5. Best Practices ✅
-
Sử Dụng Throw Với Ngoại Lệ Cụ Thể
// Không nên
throw new Exception("Lỗi chung");
// Nên
throw new IllegalArgumentException("Giá trị không hợp lệ"); -
Khai Báo Throws Rõ Ràng
// Không nên
public void process() throws Exception { }
// Nên
public void process() throws IOException, SQLException { } -
Tạo Ngoại Lệ Tùy Chỉnh Khi Cần
// Không nên
throw new RuntimeException("Lỗi nghiệp vụ");
// Nên
throw new BusinessException("Lỗi nghiệp vụ", "BIZ_001");
6. Lỗi Thường Gặp ⚠️
-
Quên Khai Báo Throws
// Lỗi
public void readFile() {
FileReader reader = new FileReader("file.txt");
}
// Đúng
public void readFile() throws FileNotFoundException {
FileReader reader = new FileReader("file.txt");
} -
Throw Ngoại Lệ Không Phù Hợp
// Lỗi
throw new IOException("Lỗi logic"); // IOException không phù hợp
// Đúng
throw new IllegalArgumentException("Lỗi logic"); -
Quên Xử Lý Ngoại Lệ Checked
// Lỗi
public void process() {
throw new CustomException("Lỗi"); // Quên throws
}
// Đúng
public void process() throws CustomException {
throw new CustomException("Lỗi");
}
7. Ví Dụ Thực Tế Nâng Cao 🎯
Xử Lý Đa Luồng
public class ThreadExceptionHandler {
public static void processWithTimeout(Runnable task, long timeout)
throws TimeoutException {
Thread thread = new Thread(task);
thread.start();
try {
thread.join(timeout);
} catch (InterruptedException e) {
throw new TimeoutException("Task bị gián đoạn");
}
if (thread.isAlive()) {
thread.interrupt();
throw new TimeoutException("Task vượt quá thời gian chờ");
}
}
}
Xử Lý Giao Dịch
public class TransactionExceptionHandler {
public static void processTransaction(Connection conn, double amount)
throws TransactionException {
try {
conn.setAutoCommit(false);
// Thực hiện các thao tác
updateBalance(conn, "sender", -amount);
updateBalance(conn, "receiver", amount);
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException ex) {
throw new TransactionException(
"Lỗi rollback giao dịch",
"TXN_001",
ex
);
}
throw new TransactionException(
"Lỗi xử lý giao dịch",
"TXN_002",
e
);
}
}
}
Xử Lý Cache
public class CacheExceptionHandler {
public static void updateCache(String key, String value)
throws CacheException {
try {
if (key == null || value == null) {
throw new CacheException(
"Key hoặc value không được null",
"CACHE_001"
);
}
// Cập nhật cache
cache.put(key, value);
} catch (Exception e) {
throw new CacheException(
"Lỗi cập nhật cache",
"CACHE_002",
e
);
}
}
}
💡 Lời khuyên: Hãy thực hành với các ví dụ thực tế để hiểu rõ hơn về cách sử dụng throw và throws trong các tình huống khác nhau.
Tiếp Theo 🎯
Trong các bài học tiếp theo, chúng ta sẽ:
- Tìm hiểu về custom exceptions
- Học cách tạo exception chaining
- Thực hành với các ví dụ thực tế
- Tìm hiểu về exception handling patterns