Java Exception Handling: try-catch-finally และ Custom Exception
#java13 เม.ย. 2569
Exception คืออะไร
Exception คือ event ที่เกิดขึ้นระหว่าง runtime ที่ทำให้โปรแกรมทำงานผิดปกติ Java มี exception hierarchy ที่ชัดเจน
Exception Hierarchy
Throwable
├── Error (ไม่ควร catch)
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception
├── RuntimeException (Unchecked)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ └── IllegalArgumentException
└── IOException (Checked)
├── FileNotFoundException
└── SQLException
try-catch-finally
try {
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
System.out.println("หารด้วยศูนย์: " + e.getMessage());
} catch (Exception e) {
System.out.println("Error อื่น: " + e.getMessage());
} finally {
System.out.println("รันเสมอ ไม่ว่าจะเกิด exception หรือไม่");
}
Multi-catch (Java 7+)
try {
// code
} catch (IOException | SQLException e) {
System.out.println("IO หรือ SQL error: " + e.getMessage());
}
try-with-resources
// ปิด resource อัตโนมัติ
try (FileReader reader = new FileReader("file.txt");
BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// reader และ br ถูกปิดอัตโนมัติ
Custom Exception
// Checked Exception
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
super("ยอดเงินไม่เพียงพอ ขาดอีก: " + amount + " บาท");
this.amount = amount;
}
public double getAmount() { return amount; }
}
// Unchecked Exception
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(int userId) {
super("ไม่พบ user id: " + userId);
}
}
// ใช้งาน
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount - balance);
}
balance -= amount;
}
Exception Chaining
try {
// database operation
} catch (SQLException e) {
throw new ServiceException("ไม่สามารถดึงข้อมูลได้", e);
}
// ServiceException
public class ServiceException extends RuntimeException {
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}
Best Practices
// ✅ Catch specific exceptions
catch (FileNotFoundException e) { ... }
// ❌ อย่า catch Exception ทั่วไปโดยไม่จำเป็น
catch (Exception e) { /* ไม่ดี */ }
// ✅ Log exception
catch (IOException e) {
logger.error("ไม่สามารถอ่านไฟล์ได้", e);
throw new ServiceException("อ่านไฟล์ล้มเหลว", e);
}
// ❌ อย่า swallow exception
catch (Exception e) { /* ว่างเปล่า - ไม่ดีมาก */ }
สรุป
การจัดการ exception ที่ดีช่วยให้ app มีความ robust ใช้ custom exception เพื่อให้ error message ชัดเจน และใช้ try-with-resources เพื่อป้องกัน resource leak ครับ