Exception Handling
try block में वो code लिखते हैं जो error दे सकता है। अगर error आए, catch block उसे "पकड़" लेता है और program crash नहीं होता।
finally block हमेशा चलता है — चाहे error आए या ना आए — जैसे cleanup करना, files बंद करना।
try {
int x = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
} finally {
System.out.println("Done trying.");
}- try = risky code
- catch = error को पकड़ता है
- finally = हमेशा चलता है
सब कुछ Throwable से शुरू होता है, जिसकी दो main branches हैं: Error (serious JVM-level problems जैसे OutOfMemoryError, StackOverflowError — इन्हें normally catch नहीं करते, कुछ नहीं कर सकते, program का environment ही खराब है) और Exception (program-level problems जिन्हें handle किया जा सकता है)।
Exception के अंदर भी दो groups हैं: RuntimeException (और उसकी subclasses — "unchecked", जैसे NullPointerException) और बाकी सब ("checked", जैसे IOException)। यह distinction अगले subtopic में detail से है।
| Level | Examples | Handle करना चाहिए? |
|---|---|---|
| Throwable | (root of everything) | — |
| Error | OutOfMemoryError, StackOverflowError | Normally नहीं (environment issue) |
| Checked Exception | IOException, SQLException | हाँ, compiler force करता है |
| RuntimeException (unchecked) | NullPointerException, ArithmeticException | Optional, लेकिन अच्छी practice है |
NullPointerException (NPE) सबसे common है — जब null object पर method call या field access करो। ArrayIndexOutOfBoundsException — array का index range से बाहर (जैसे size-5 array में index 5 access करना, जबकि valid indices 0-4 हैं)। ArithmeticException — जैसे integer को 0 से divide करना (10/0 exception देता है, लेकिन 10.0/0 नहीं — double में "Infinity" मिलता है!)।
ClassCastException — गलत type cast (जैसे Object o = "text"; Integer i = (Integer) o;)। NumberFormatException — जैसे Integer.parseInt("abc") (जो number ही नहीं है)। IllegalArgumentException — method को गलत/invalid argument दिया (जैसे negative age)।
| Exception | कब आती है |
|---|---|
| NullPointerException | null object पर method/field access |
| ArrayIndexOutOfBoundsException | Array का गलत index |
| ArithmeticException | Integer को 0 से divide |
| ClassCastException | गलत type cast |
| NumberFormatException | Invalid String को number में convert करना |
| IllegalArgumentException | Method को invalid argument |
अगर try block में return statement हो, finally *फिर भी* चलता है (return होने से पहले) — Java guarantee देता है finally का execution।
और अगर finally में भी return हो, तो वो try/catch के return को "override" कर देता है — यह confusing behavior है (try का return value silently discard हो जाता है), इसलिए finally block में return लिखना best practice में हमेशा avoid किया जाता है।
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 करो — specific exception catch करो (जैसे catch (IOException e)) ताकि पता रहे exactly क्या गलत हुआ, और unrelated exceptions accidentally "swallow" न हो जाएं।
कभी भी खाली catch block मत लिखो (catch(e){}) — error silently गायब हो जाता है और debug करना nightmare बन जाता है। कम से कम log तो करो (e.printStackTrace() या proper logging framework)।
Exception का message meaningful रखो — "Error occurred" कुछ नहीं बताता, "Failed to connect to database at " + url ज़्यादा useful है debugging के लिए।