In this tutorial, you’ll learn everything about Exception Handling in Java — what it is, why we use it, its types (checked and unchecked), and how to handle it effectively in real-world projects. We’ll also cover 10 interview questions, 10 scenario-based questions (for experienced developers), and 10 tricky coding questions often asked in Java interviews.
1. What is Exception Handling in Java?
Exception Handling in Java is a mechanism that allows you to handle runtime errors gracefully, preventing your program from crashing.
Instead of abrupt termination, Java lets you control what happens when something goes wrong using keywords like try, catch, finally, throw, and throws.
2. Why Do We Use Exception Handling?
- Maintain normal flow: Prevents the application from sudden termination.
- Better debugging: Gives clear error information through stack traces or logs.
- Separation of concerns: Keeps business logic separate from error-handling logic.
- Robustness: Increases application reliability and user trust.
3. Types of Exceptions
A. Checked Exceptions (Compile-Time)
Checked exceptions are checked by the compiler at compile-time.
You must either handle them using try-catch or declare them using throws.
Examples: IOException, SQLException, FileNotFoundException
Use When: Dealing with external resources like files, databases, or network calls that may fail.
B. Unchecked Exceptions (Runtime)
Unchecked exceptions occur at runtime and are not checked during compilation. They usually result from logical or coding errors.
Examples: NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException
Use When: Handling unexpected or programming-level issues that can occur during execution.
C. Errors
Errors represent serious issues that cannot be recovered from (e.g., JVM crash, memory overflow).
Examples include OutOfMemoryError and StackOverflowError.
4. Basic Syntax Example
try {
int a = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero");
} finally {
System.out.println("This block always executes");
}
5. Real-World Example: Payment Processing
public void processPayment(double amount) throws IOException {
if (amount <= 0)
throw new IllegalArgumentException("Invalid payment amount");
try {
connectToBankServer();
} catch (IOException e) {
System.out.println("Network issue: " + e.getMessage());
throw e;
} finally {
System.out.println("Closing payment session...");
}
}
✅ Checked Exception: IOException (network issue)
✅ Unchecked Exception: IllegalArgumentException (invalid input)
6. Key Exception Handling Keywords
| Keyword | Description |
|---|---|
try | Defines code that might throw an exception. |
catch | Handles specific exception types. |
finally | Executes cleanup logic regardless of exception. |
throw | Manually throws an exception. |
throws | Declares exceptions a method might throw. |
7. Top 10 Interview Questions and Answers
- What is exception handling in Java?
It’s a mechanism to handle runtime errors and maintain program flow. - Difference between checked and unchecked exceptions?
Checked: compile-time; must handle. Unchecked: runtime; optional to handle. - Can we use multiple catch blocks?
Yes, to handle different exception types separately. - Can
finallyblock be skipped?
Only if JVM exits or a fatal error occurs. - Difference between
throwandthrows?throwis used to throw an exception manually;throwsdeclares possible exceptions. - What happens if no catch matches?
The exception propagates up and may terminate the program. - Can we catch multiple exceptions in one block?
Yes, usingcatch (IOException | SQLException e). - Can we handle errors?
Technically yes, but it’s not recommended. - What is exception chaining?
Wrapping one exception into another to preserve cause. - What is custom exception?
User-defined class extendingExceptionorRuntimeException.
8. 10 Advanced Scenario-Based Questions (Experienced Level)
1️⃣ Payment Gateway Timeout
try {
paymentGateway.process(paymentRequest);
} catch (IOException e) {
log.error("Payment timeout", e);
throw new PaymentException("Payment failed", e);
}
✅ Graceful failure and clear logging.
2️⃣ Database Transaction Failure
@Transactional
public void updateOrder(Long id, String status) {
try {
orderRepo.updateStatus(id, status);
} catch (SQLException e) {
throw new DatabaseException("Failed to update order", e);
}
}
✅ Rollback automatically via @Transactional.
3️⃣ Debugging NullPointerException
String email = Optional.ofNullable(user.getEmail())
.orElseThrow(() -> new InvalidDataException("Email is missing"));
4️⃣ File Upload Error
try (FileInputStream fis = new FileInputStream(file)) {
// process file
} catch (FileNotFoundException e) {
throw new FileProcessingException("Uploaded file missing", e);
}
5️⃣ Retry Mechanism for API Calls
for (int i = 0; i < 3; i++) {
try {
callExternalAPI();
break;
} catch (IOException e) {
if (i == 2) throw new APIException("API failed after retries", e);
Thread.sleep(1000);
}
}
6️⃣ Custom Validation Exception
if (!email.contains("@")) {
throw new ValidationException("Invalid email format");
}
7️⃣ Exception in Finally Block
try (FileInputStream fis = new FileInputStream("data.txt")) {
// auto-close handles exceptions safely
}
8️⃣ Propagation Across Layers
// DAO
throw new SQLException("DB error");
// Service
catch (SQLException e) { throw new DatabaseException("Cannot fetch user", e); }
// Controller
@ExceptionHandler(DatabaseException.class)
public ResponseEntity handleDB(DatabaseException e) {
return ResponseEntity.status(500).body(e.getMessage());
}
9️⃣ Global Exception Handling
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(PaymentException.class)
public ResponseEntity handlePayment(PaymentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
🔟 Exception in Executor Threads
Future future = executor.submit(() -> riskyOperation());
try {
future.get();
} catch (ExecutionException e) {
log.error("Async task failed: " + e.getCause());
}
9. 10 Tricky Coding Questions and Answers
Output → 30 (finally overrides return).try { return 10; } catch (Exception e) { return 20; } finally { return 30; }
Output:try { int a = 5/0; } catch (ArithmeticException e) { System.out.println("Catch"); } finally { System.out.println("Finally"); }
Catch
Finally
Output:try { System.out.println("Try"); } finally { System.out.println("Finally"); }
Try
Finally
Output → Errortry { throw new RuntimeException("Error"); } catch (Exception e) { System.out.println(e.getMessage()); }
Output → Nothing (finally not executed).try { System.exit(0); } finally { System.out.println("Finally"); }
Compilation error — must handle checked exception.public static void test() throws Exception { throw new IOException(); }
Output → Handledtry { int[] arr = new int[3]; arr[5] = 10; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Handled"); }
Output → Caughttry { throw new NullPointerException("Null"); } catch (RuntimeException e) { System.out.println("Caught"); }
Output → Invalid numbertry { int x = Integer.parseInt("abc"); } catch (NumberFormatException e) { System.out.println("Invalid number"); }
Output → Custom errorclass CustomException extends Exception { public CustomException(String msg) { super(msg); } } try { throw new CustomException("Custom error"); } catch (CustomException e) { System.out.println(e.getMessage()); }
10. Summary Table
| Type | When to Use | Example |
|---|---|---|
| Checked | External resources like file, DB, network | IOException, SQLException |
| Unchecked | Programming logic issues | NullPointerException, ArithmeticException |
Conclusion
That’s it! 🎯 You’ve learned everything about Exception Handling in Java — from basics to advanced scenarios and interview-level insights.
By following these practices, you can build robust, fault-tolerant applications that handle errors gracefully and maintain smooth flow even during failures.
Next Step: Learn how to implement GlobalExceptionHandler in Spring Boot for centralized exception management.
0 Comments