Cosmic Module

J

Qubits of DPK

March 14, 2026

Core Java

Layman Explanation

You're driving and suddenly a tyre punctures. You don't abandon the car — you handle it: pull over, change the tyre, continue. Exception handling is Java's way of dealing with unexpected problems gracefully without crashing the program.

What is an Exception?

An abnormal condition that disrupts the normal flow of a program.
javascript
QUBITS OF DPK
1Exception Types
23├── Checked Exception     → compile-time, MUST handle
4   (IOException, SQLException, FileNotFoundException)
56└── Unchecked Exception   → runtime, handling optional
7    (NullPointerException, ArrayIndexOutOfBoundsException,
8     ClassCastException, ArithmeticException)

Exception Hierarchy

javascript
QUBITS OF DPK
1Throwable
23├── ErrorJVM problems, don't catch these
4   (StackOverflowError, OutOfMemoryError)
56└── Exception
7    ├── IOExceptionChecked
8    ├── SQLExceptionChecked
9    └── RuntimeExceptionUnchecked
10        ├── NullPointerException
11        ├── ArithmeticException
12        ├── ArrayIndexOutOfBoundsException
13        └── ClassCastException

try-catch-finally

java
QUBITS OF DPK
1try {
2    // risky code
3    int result = 10 / 0;
4} catch (ArithmeticException e) {
5    // handle specific exception
6    System.out.println("Division by zero: " + e.getMessage());
7} catch (Exception e) {
8    // catch all others
9    System.out.println("Error: " + e.getMessage());
10} finally {
11    // ALWAYS runs — even if exception or return!
12    System.out.println("Cleanup done.");
13}

Multiple Catch

java
QUBITS OF DPK
1try {
2    String s = null;
3    System.out.println(s.length());   // NullPointerException
4    int[] arr = new int[3];
5    arr[5] = 10;                       // ArrayIndexOutOfBoundsException
6} catch (NullPointerException e) {
7    System.out.println("Null!");
8} catch (ArrayIndexOutOfBoundsException e) {
9    System.out.println("Array out of bounds!");
10} catch (Exception e) {
11    System.out.println("General error");
12    // ⚠️ specific catches MUST come before general!
13}

throw vs throws

throw — explicitly throw exception

java
QUBITS OF DPK
1void checkAge(int age) {
2    if (age < 18) {
3        throw new IllegalArgumentException("Must be 18+");
4    }
5    System.out.println("Access granted");
6}

throws — declare exception (duck it)

java
QUBITS OF DPK
1void readFile(String path) throws IOException {
2    // not handling, passing responsibility to caller
3    FileReader fr = new FileReader(path);
4}
5
6// Caller must handle it
7try {
8    readFile("/some/path");
9} catch (IOException e) {
10    System.out.println("File not found!");
11}

Custom Exception

java
QUBITS OF DPK
1class InsufficientFundsException extends Exception {
2    private double amount;
3
4    InsufficientFundsException(double amount) {
5        super("Insufficient funds. Required: " + amount);
6        this.amount = amount;
7    }
8
9    double getAmount() { return amount; }
10}
11
12class BankAccount {
13    private double balance;
14
15    void withdraw(double amount) throws InsufficientFundsException {
16        if (amount > balance) {
17            throw new InsufficientFundsException(amount);
18        }
19        balance -= amount;
20    }
21}

try-with-resources (Java 7+)

java
QUBITS OF DPK
1// OLD way — must close manually
2BufferedReader br = null;
3try {
4    br = new BufferedReader(new FileReader("file.txt"));
5    String line = br.readLine();
6} catch (IOException e) {
7    e.printStackTrace();
8} finally {
9    if (br != null) br.close();   // manual close
10}
11
12// NEW way — auto-close with try-with-resources
13try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
14    String line = br.readLine();
15} catch (IOException e) {
16    e.printStackTrace();
17}
18// br automatically closed! Resource must implement AutoCloseable

Production Use Case

java
QUBITS OF DPK
1// Netflix API service — global exception handling
2@ControllerAdvice
3public class GlobalExceptionHandler {
4
5    @ExceptionHandler(ResourceNotFoundException.class)
6    public ResponseEntity<String> handleNotFound(ResourceNotFoundException e) {
7        return ResponseEntity.status(404).body(e.getMessage());
8    }
9
10    @ExceptionHandler(Exception.class)
11    public ResponseEntity<String> handleAll(Exception e) {
12        return ResponseEntity.status(500).body("Internal Server Error");
13    }
14}
15// Custom exceptions + Spring's @ControllerAdvice = clean error handling

️ All Traps

java
QUBITS OF DPK
1// Trap 1 — Catching parent before child
2catch (Exception e) { }           // ❌ catches everything, child never reached
3catch (NullPointerException e) { } // unreachable!
4// Fix: specific → general order
5
6// Trap 2 — Empty catch block (swallowing exception)
7try {
8    riskyCode();
9} catch (Exception e) { }  // ❌ silent failure! Hard to debug.
10// Always at least: e.printStackTrace() or log it
11
12// Trap 3 — finally always runs
13try {
14    return 1;
15} finally {
16    System.out.println("finally!");  // runs even before return!
17    return 2;   // ⚠️ overrides return 1! Very tricky!
18}
19
20// Trap 4 — throw vs throws
21throw new Exception();    // actually throws
22throws Exception          // just declares, doesn't throw
23
24// Trap 5 — Checked exceptions MUST be handled
25void read() throws IOException { }   // caller MUST catch or declare throws

Interview Answer (SDE-2)

"Exception handling prevents program crashes by handling abnormal conditions gracefully. Checked exceptions must be handled at compile time (IOException, SQLException). Unchecked exceptions are runtime failures (NPE, ClassCast). try-catch-finally handles exceptions — finally always runs for cleanup. throw explicitly throws; throws declares that a method may throw. Custom exceptions extend Exception for domain-specific errors. try-with-resources auto-closes resources implementing AutoCloseable. In production Spring Boot, @ControllerAdvice with @ExceptionHandler centralizes exception handling across all endpoints."

Interview Questions & MAANG-Level Answers

Q1. What is the difference between checked and unchecked exceptions?
Checked exceptions: subclasses of Exception (not RuntimeException) — MUST be handled at compile time via try-catch or throws declaration. Examples: IOException, SQLException, FileNotFoundException. Force the caller to acknowledge that something can go wrong. Unchecked exceptions: subclasses of RuntimeException — handling is optional, not enforced by compiler. Examples: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException. Represent programming errors that should ideally be prevented, not caught.
Q2. What is the exception hierarchy in Java?
javascript
QUBITS OF DPK
1Throwable
2├── Error (JVM problems — don't catch)
3│   ├── StackOverflowError
4│   └── OutOfMemoryError
5└── Exception
6    ├── IOException (checked)
7    ├── SQLException (checked)
8    └── RuntimeException (unchecked)
9        ├── NullPointerException
10        ├── ArithmeticException
11        └── ArrayIndexOutOfBoundsException
Q3. What is the difference between throw and throws?
throw is a statement that actually throws an exception object: throw new IllegalArgumentException("invalid"). throws is a declaration in method signature that warns callers the method might throw a checked exception: void read() throws IOException. throw is used inside method body; throws is in method signature. You can throw unchecked exceptions without declaring throws.
Q4. What is finally and when does it NOT run?
finally always executes after try-catch, regardless of whether an exception occurred or was caught — used for guaranteed cleanup (close connections, release locks). When it does NOT run: (1) System.exit() is called — JVM shuts down immediately. (2) JVM crashes (OOME, kill signal). (3) Infinite loop inside try block. Gotcha: if finally has a return statement, it overrides the try block's return, which is a subtle bug to avoid.
Q5. What is try-with-resources and why was it introduced?
Introduced in Java 7 to automatically close resources (files, connections, streams) that implement AutoCloseable. Before: you had to close in finally with null checks — verbose and error-prone. With try-with-resources:
java
QUBITS OF DPK
1try (Connection conn = ds.getConnection();
2     PreparedStatement ps = conn.prepareStatement(sql)) {
3    // use resources
4}  // auto-closes ps first, then conn, even if exception occurs
Resources are closed in reverse order. Exception during close is suppressed (accessible via getSuppressed()).
Q6. How do you create a custom exception?
Extend Exception for checked, RuntimeException for unchecked. Include message and optional cause:
java
QUBITS OF DPK
1public class InsufficientFundsException extends RuntimeException {
2    private final double required;
3    public InsufficientFundsException(double required) {
4        super("Insufficient funds. Required: " + required);
5        this.required = required;
6    }
7    public double getRequired() { return required; }
8}
9// Throw: throw new InsufficientFundsException(500.0);
10// Catch: catch (InsufficientFundsException e) { e.getRequired(); }
In Spring Boot: use @ResponseStatus annotation on custom exceptions for automatic HTTP status mapping.
Q7. What is the order of catch blocks?
More specific (child) exceptions MUST come before more general (parent) ones. If Exception is caught first, all child exceptions are unreachable — compile error. Order: NullPointerException before RuntimeException before Exception. Multi-catch (Java 7+) for same handling: catch (IOException | SQLException e) {}.
Q8. What is the difference between Error and Exception?
Error: serious JVM-level problems that applications shouldn't try to recover from (StackOverflowError, OutOfMemoryError, AssertionError). Catching Errors is strongly discouraged — the JVM is in an unstable state. Exception: recoverable application-level problems — should be caught and handled. Both extend Throwable. In production: if you get StackOverflowError — fix the recursion. OutOfMemoryError — fix the memory leak or increase heap (like your notification service fix!).