Exception Handling
You put code that might error out inside the try block. If an error occurs, the catch block "catches" it and the program doesn't crash.
The finally block always runs — whether an error occurred or not — like doing cleanup, closing files.
try {
int x = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
} finally {
System.out.println("Done trying.");
}Sab kuch Throwable se shuru hota hai, jiske do main branches hain: Error (serious JVM-level problems jaise OutOfMemoryError, StackOverflowError — inhe normally catch nahi karte, kuch nahi kar sakte, program ka environment hi kharab hai) aur Exception (program-level problems jinhe handle kiya ja sakta hai).
Exception ke andar bhi do groups hain: RuntimeException (aur uski subclasses — "unchecked", jaise NullPointerException) aur baaki sab ("checked", jaise IOException). Ye distinction agla subtopic mein detail se hai.
| Level | Examples | Handle karna chahiye? |
|---|---|---|
| Throwable | (root of everything) | — |
| Error | OutOfMemoryError, StackOverflowError | Normally nahi (environment issue) |
| Checked Exception | IOException, SQLException | Haan, compiler force karta hai |
| RuntimeException (unchecked) | NullPointerException, ArithmeticException | Optional, lekin achhi practice hai |
NullPointerException (NPE) sabse common hai — jab null object par method call ya field access karo. ArrayIndexOutOfBoundsException — array ka index range se bahar (jaise size-5 array mein index 5 access karna, jabki valid indices 0-4 hain). ArithmeticException — jaise integer ko 0 se divide karna (10/0 exception deta hai, lekin 10.0/0 nahi — double mein "Infinity" milta hai!).
ClassCastException — galat type cast (jaise Object o = "text"; Integer i = (Integer) o;). NumberFormatException — jaise Integer.parseInt("abc") (jo number hi nahi hai). IllegalArgumentException — method ko galat/invalid argument diya (jaise negative age).
| Exception | Kab Aati Hai |
|---|---|
| NullPointerException | null object par method/field access |
| ArrayIndexOutOfBoundsException | Array ka galat index |
| ArithmeticException | Integer ko 0 se divide |
| ClassCastException | Galat type cast |
| NumberFormatException | Invalid String ko number mein convert karna |
| IllegalArgumentException | Method ko invalid argument |
Agar try block mein return statement ho, finally *phir bhi* chalta hai (return hone se pehle) — Java guarantee deta hai finally ka execution.
Aur agar finally mein bhi return ho, to wo try/catch ke return ko "override" kar deta hai — ye confusing behavior hai (try ka return value silently discard ho jaata hai), isliye finally block mein return likhना best practice mein hamesha avoid kiya jaata hai.
static int test() {
try {
return 1;
} finally {
System.out.println("finally chalega return se pehle bhi");
// return 2; // agar ye line hoti, to method 2 return karta, 1 nahi!
}
}Generic "catch (Exception e)" avoid karo — specific exception catch karo (jaise catch (IOException e)) taaki pata rahe exactly kya galat hua, aur unrelated exceptions accidentally "swallow" na ho jaayein.
Kabhi bhi khaali catch block mat likho (catch(e){}) — error silently gayab ho jaata hai aur debug karna nightmare ban jaata hai. Kam se kam log to karo (e.printStackTrace() ya proper logging framework).
Exception ka message meaningful rakho — "Error occurred" kuch nahi batata, "Failed to connect to database at " + url zyada useful hai debugging ke liye.