Java Exceptions & I/O

Exceptions & File I/O

How Java handles the things that go wrong — a typed exception hierarchy the compiler helps you respect, plus reading and writing files safely.

Java 21 3 Topics
01

try / catch / finally

Wrap risky code in try, handle failures in catch, and put cleanup that must always run in finally. You can catch multiple exception types, most specific first.

Java — try / catch / finally
try {
    int result = 10 / 0;      // throws ArithmeticException
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero: " + e.getMessage());
} catch (Exception e) {   // broader fallback — must come AFTER specific ones
    System.out.println("Something else failed");
} finally {
    System.out.println("Always runs — cleanup goes here");
}

// throw your own exception
if (age < 0) throw new IllegalArgumentException("age cannot be negative");
02

Checked vs Unchecked

This is Java's signature exception feature. Checked exceptions must be declared or handled — the compiler enforces it. Unchecked exceptions (subclasses of RuntimeException) are programming bugs that don't need declaring.

CheckedUnchecked (RuntimeException)
Compiler enforces?Yes — declare or handleNo
RepresentsRecoverable external problemsProgramming bugs
ExamplesIOException, SQLExceptionNullPointerException, ArrayIndexOutOfBounds
Handlingthrows in signature or try/catchFix the bug instead of catching
Java — throws & custom exception
// checked — the throws clause is mandatory
void readFile(String path) throws IOException {
    Files.readString(Path.of(path));
}

// custom exception
class InsufficientFundsException extends Exception {
    InsufficientFundsException(String msg) { super(msg); }
}
Checked exceptions are unique to Java — most languages (Python, JavaScript, C++) have only the unchecked kind. They force you to acknowledge failures at compile time, which some love and some find noisy.
03

File I/O with try-with-resources

try-with-resources auto-closes anything that implements AutoCloseable (files, streams, sockets) — no matter how the block exits. It's the safe, modern way to do I/O without leaking resources.

Java — Reading & Writing Files
import java.nio.file.*;
import java.io.*;

// Simplest — read/write whole file (Java 11+)
String text = Files.readString(Path.of("data.txt"));
Files.writeString(Path.of("out.txt"), "Hello");

// try-with-resources — reader auto-closes even on exception
try (BufferedReader br = Files.newBufferedReader(Path.of("data.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    System.err.println("Read failed: " + e.getMessage());
}
// no finally needed — br.close() is called automatically
Before try-with-resources (Java 7), you closed resources in a finally block — and forgetting one, or the close itself throwing, was a common leak. The resource declared in try(...) is always closed for you.

Quick Quiz

1. The finally block runs…
2. Checked exceptions are…
3. NullPointerException is…
4. try-with-resources is used for…
5. When catching multiple exceptions, you list…