Advanced Exception Handling
Ek catch block mein "|" se multiple exception types pakad sakte ho: catch (IOException | SQLException e).
Custom exceptions ka apna hierarchy bana sakte ho — jaise ek base AppException, aur usse extend karke specific PaymentFailedException — bade projects mein errors ko organize karta hai.
try {
riskyOperation();
} catch (IOException | SQLException e) {
System.out.println("Handled: " + e.getMessage());
}
class AppException extends Exception {}
class PaymentFailedException extends AppException {}Koi bhi class jo AutoCloseable interface implement karti hai (FileReader, Scanner, database Connection, etc.) try-with-resources mein use ho sakti hai. try(...) ke andar resource declare karo, aur block khatam hote hi (chahe normally ya exception se) close() automatically call ho jaata hai — manually finally mein close() likhने ki zaroorat khatam.
Java 9+ mein resource ko try() ke bahar bhi declare kar sakte ho (agar wo effectively final ho) aur sirf naam try() mein likh sakte ho — thoda cleaner syntax.
try (Scanner sc = new Scanner(System.in)) {
String input = sc.nextLine();
} // sc.close() automatically ho gaya
// Multiple resources bhi ek saath:
try (FileReader fr = new FileReader("a.txt"); FileWriter fw = new FileWriter("b.txt")) {
// dono automatically close honge, reverse order mein
}Custom exception banate waqt: meaningful naam do (InsufficientBalanceException, na ki MyException ya Exception1), Exception ya RuntimeException extend karo (checked vs unchecked decide karke — is subtopic ke last point mein detail hai), aur ek constructor do jo message accept kare aur super(message) call kare.
Extra fields bhi add kar sakte ho custom exception mein — jaise InsufficientBalanceException mein "shortfallAmount" field, taaki catch karne wala code us extra info ko use kar sake.
class InsufficientBalanceException extends RuntimeException {
final double shortfall;
InsufficientBalanceException(String message, double shortfall) {
super(message);
this.shortfall = shortfall;
}
}Kabhi-kabhi ek exception doosre exception ki wajah se aati hai — "cause" ke through original exception ko wrap kar sakte ho, taaki original root-cause ki info khoye nahi (stack trace mein "Caused by:" dikhta hai). new CustomException("msg", originalException) jaisa pattern — dusra argument "cause" hai.
try {
readFile();
} catch (IOException e) {
throw new ServiceException("File load fail hua", e); // cause preserved
}Checked exception (jo Exception extend kare, RuntimeException nahi) use karo jab caller ko *zaroor* handle karna chahiye, aur recovery possible ho (jaise file not found — retry ya alternate path try kar sakte ho). Compiler force karta hai ki ya to try-catch karo, ya throws se aage pass karo.
Unchecked (RuntimeException) use karo programming errors ke liye jo bugs hain, recovery normally nahi hoti (jaise invalid argument pass karna, null pointer) — inhe har jagah try-catch karna majboori nahi hai, compiler force nahi karta.
| Checked | Unchecked (RuntimeException) | |
|---|---|---|
| Compiler force karta hai handle karna? | Haan | Nahi |
| Example | IOException, SQLException | NullPointerException, IllegalArgumentException |
| Kab use karein | Recoverable, external problems | Programming bugs, logic errors |