# Exception Handling in Java — try, catch, finally, throw, throws

Source: https://skills101.in/learn/java/java-exception-handling — Skills101 free tutorial (Java Programming). Updated 2026-11-09.

An **exception** is an event that breaks the normal flow of a program — dividing by zero, a missing file, a null reference. Handling exceptions lets the program respond sensibly instead of crashing.

![Java exception hierarchy: Throwable splits into Error (like OutOfMemoryError — don't catch) and Exception; Exception splits into checked exceptions (like IOException — must catch or declare) and unchecked RuntimeExceptions (like NullPointerException)](https://skills101.in/learn-img/java/exception-tree.svg)

## 1. Checked vs unchecked

| | Checked | Unchecked |
|---|---|---|
| Examples | `IOException`, `SQLException` | `NullPointerException`, `ArithmeticException`, `ArrayIndexOutOfBoundsException` |
| Parent | `Exception` | `RuntimeException` |
| Compiler forces handling? | **yes** — catch it or declare `throws` | no |
| Usually caused by | the outside world (files, network) | **bugs** in your code |

**Errors** (`OutOfMemoryError`, `StackOverflowError`) are serious JVM problems — you don't catch them; you fix the cause.

## 2. try, catch, finally

```java
public class Main {
    public static void main(String[] args) {
        int[] marks = {80, 90};
        try {
            System.out.println("Start");
            System.out.println(marks[5]);          // throws
            System.out.println("not printed");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Caught: " + e.getMessage());
        } finally {
            System.out.println("finally always runs");
        }
        System.out.println("Program continues");
    }
}
```

```text
Start
Caught: Index 5 out of bounds for length 2
finally always runs
Program continues
```

### Multiple catches and multi-catch

```java
public class Main {
    static String parse(String s) {
        try {
            int n = Integer.parseInt(s);
            return "100 / " + n + " = " + (100 / n);
        } catch (NumberFormatException | ArithmeticException e) {
            return "Bad input: " + e.getClass().getSimpleName();
        }
    }
    public static void main(String[] args) {
        System.out.println(parse("4"));
        System.out.println(parse("abc"));
        System.out.println(parse("0"));
    }
}
```

```text
100 / 4 = 25
Bad input: NumberFormatException
Bad input: ArithmeticException
```

> When using separate catch blocks, put **specific** exceptions before general ones (`Exception` last), or the code won't compile.

## 3. throw vs throws

- **`throw`** actually throws an exception object: `throw new IllegalArgumentException("…")`.
- **`throws`** in a method signature **declares** that the method may throw a checked exception.

```java
class InsufficientBalanceException extends Exception {     // custom checked exception
    InsufficientBalanceException(String msg) { super(msg); }
}

class Account {
    private double balance = 500;
    void withdraw(double amt) throws InsufficientBalanceException {
        if (amt > balance) throw new InsufficientBalanceException("Need ₹" + (amt - balance) + " more");
        balance -= amt;
    }
}

public class Main {
    public static void main(String[] args) {
        Account acc = new Account();
        try {
            acc.withdraw(200);
            acc.withdraw(800);
        } catch (InsufficientBalanceException e) {
            System.out.println(e.getMessage());
        }
    }
}
```

```text
Need ₹500.0 more
```

## 4. try-with-resources

Resources like files and database connections must be closed. Declare them in `try (...)` and Java closes them automatically:

```java
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File f = File.createTempFile("notes", ".txt");
        try (PrintWriter out = new PrintWriter(new FileWriter(f))) {
            out.println("line one");
            out.println("line two");
        }
        try (BufferedReader in = new BufferedReader(new FileReader(f))) {
            String line;
            while ((line = in.readLine()) != null) System.out.println(line.toUpperCase());
        }
        f.delete();
    }
}
```

```text
LINE ONE
LINE TWO
```

## 5. final vs finally vs finalize (interview favourite)

- **final** — keyword: constant variable, non-overridable method, non-extendable class.
- **finally** — block that always runs after try/catch.
- **finalize()** — an old method the garbage collector *might* call before destroying an object; **deprecated** — don't use it.

## Common mistakes

- Catching `Exception` everywhere and hiding real bugs.
- Empty catch blocks (`catch (Exception e) {}`) — at least log the error.
- Using exceptions for normal flow control.

## Quick recap

- Throwable → Error / Exception → checked vs RuntimeException (unchecked).
- try / catch (specific first) / finally (always).
- `throw` an object; `throws` declares; custom exceptions extend Exception or RuntimeException.
- try-with-resources closes files and connections automatically.


Practice quiz and free certificate: https://skills101.in/learn/java/java-exception-handling