Interview question
What happens if an exception is thrown inside a finally block? finally block के अंदर exception throw हो तो क्या होता है?
Answer
An exception thrown in finally SUPPRESSES any exception from the try or catch block - only the finally block's exception propagates, and the original is lost unless explicitly captured.
public void problematic() {
try {
throw new RuntimeException('Original exception from try');
} finally {
throw new RuntimeException('Exception from finally'); // this WINS
}
}
public static void main(String[] args) {
try {
new Main().problematic();
} catch (RuntimeException e) {
System.out.println(e.getMessage()); // 'Exception from finally' - original is LOST
}
}
// This is considered a BAD PRACTICE because it silently discards
// the original error information, making debugging harder
// SAFER pattern - avoid throwing new exceptions in finally;
// only use finally for cleanup that itself shouldn't fail
public void safer() {
Connection conn = null;
try {
conn = openConnection();
performWork(conn);
} finally {
if (conn != null) {
try {
conn.close(); // wrap risky cleanup in its own try-catch
} catch (Exception closeException) {
System.out.println('Failed to close, but not masking original error');
}
}
}
}
// try-with-resources handles this better automatically via 'suppressed exceptions'
// - if both the try block AND close() throw, the close() exception is
// added to the ORIGINAL exception's getSuppressed() array, not lost
try (MyResource r = new MyResource()) {
throw new RuntimeException('try block error');
}
// catch (RuntimeException e) { e.getSuppressed(); } would show close() errors toofinally में throw हुई exception try या catch की exception को suppress कर देती है - सिर्फ finally की exception propagate होती है, original explicitly capture न करने पर खो जाती है।
public void problematic() {
try {
throw new RuntimeException('try से original exception');
} finally {
throw new RuntimeException('finally से exception'); // यह जीतती है
}
}
public static void main(String[] args) {
try {
new Main().problematic();
} catch (RuntimeException e) {
System.out.println(e.getMessage()); // 'finally से exception' - original खो गई
}
}
// यह bad practice है क्योंकि original error information चुपचाप खो जाती है
// सुरक्षित pattern - finally में नई exceptions throw करने से बचें
public void safer() {
Connection conn = null;
try {
conn = openConnection();
performWork(conn);
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception closeException) {
System.out.println('Close fail हुआ, original error mask नहीं हुआ');
}
}
}
}
// try-with-resources इसे बेहतर handle करता है 'suppressed exceptions' से
try (MyResource r = new MyResource()) {
throw new RuntimeException('try block error');
}
// e.getSuppressed() से close() की errors भी दिखेंगीWas this answer clear?