Lesson 8 / 11

Exception Handling and What’s Next

Try/catch

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Can't divide by zero: " + e.getMessage());
} finally {
    System.out.println("This always runs.");
}

finally runs whether an exception was thrown or not — it’s the right place for cleanup code, like closing a file or a network connection, that absolutely must happen no matter what.

Checked vs unchecked exceptions

Checked exceptions (like IOException) must be either caught or explicitly declared with throws in the method signature — the compiler forces you to acknowledge them. Unchecked exceptions (like ArithmeticException above) don’t require that; they usually signal a genuine bug in the code rather than an expected, recoverable failure.

public void readFile(String path) throws IOException {
    // ... code that might throw IOException
}

Throwing your own exceptions

public void enroll(int studentId) {
    if (studentId <= 0) {
        throw new IllegalArgumentException("Student ID must be positive");
    }
    // ... enrollment logic
}

Throwing a clear, specific exception the moment something is invalid — rather than letting a program continue with bad data and fail confusingly somewhere else later — is standard defensive practice in Java, and makes bugs dramatically easier to trace back to their real cause.

Multiple catch blocks

try {
    riskyOperation();
} catch (IOException e) {
    System.out.println("File problem: " + e.getMessage());
} catch (ArithmeticException e) {
    System.out.println("Math problem: " + e.getMessage());
}

You can catch different exception types separately and respond to each one appropriately — a file-not-found error and a division-by-zero error usually call for very different recovery logic.

Onward to the advanced lessons

You now know Java’s syntax, methods, OOP fundamentals, and exception handling. The next three lessons take you to a professional level: generics, streams, and multithreading.