JV

Java Fundamentals

19 lessons

Progress0%
1. Introduction to Java
1What is Java?
2. Variables and Data Types
1Primitive Types
3. Control Flow
ConditionalsLoops
4. Methods
Defining MethodsMethod Overloading
5. Object-Oriented Programming
Classes and ObjectsInheritanceInterfaces and Abstract Classes
6. Collections
ArrayList and LinkedListHashMap and HashSet
7. Exception Handling
Checked & Unchecked Exceptionstry-with-resources & Custom Exceptions
8. Generics
Generic Classes & MethodsWildcards & Type Erasure
9. Modern Java
Lambdas & Functional InterfacesStream API & Optional
10. File I/O
java.nio.file APIBuffered I/O & try-with-resources
All Tutorials
JavaException Handling
Lesson 12 of 19 min
Chapter 7 · Lesson 1

Checked & Unchecked Exceptions

Exception handling is one of Java's most important reliability features. It provides a structured mechanism for detecting, reporting, and recovering from errors at runtime.

The Exception Hierarchy

Java's exception system is built on a class hierarchy rooted at Throwable:

  • Throwable
    • Error — serious JVM problems (OutOfMemoryError, StackOverflowError). Do not catch these.
    • Exception — recoverable conditions that programs should handle.
      • RuntimeException — unchecked exceptions (programming mistakes).

Checked vs Unchecked Exceptions

Checked exceptions extend Exception (but not RuntimeException). The compiler forces you to either handle them with try/catch or declare them with throws in the method signature. Examples: IOException, SQLException, ParseException.

Unchecked exceptions extend RuntimeException. The compiler does not require you to handle them, though you can. Examples: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, NumberFormatException.

try / catch / finally

The try block contains code that may throw. One or more catch blocks handle specific exception types — more specific types must appear before more general ones. The optional finally block always executes whether an exception occurred or not, making it ideal for releasing resources.

Multi-catch (Java 7+)

When two exceptions require identical handling you can combine them in a single catch clause with the pipe operator: catch (IOException | SQLException e). The catch parameter is implicitly final in multi-catch.

throw vs throws

  • throw (lowercase) is a statement that actually throws an exception object: throw new IllegalArgumentException("msg");
  • throws (with s) is part of a method declaration that advertises which checked exceptions callers must handle.

Reading Stack Traces

When an exception propagates uncaught, Java prints a stack trace showing the exception type, message, and the call chain from the throw site down to main. The topmost frame is closest to the source of the problem. Reading stack traces is an essential debugging skill.

Code Examples

Basic try / catch / finallyjava
public class TryCatchDemo {
    public static int divide(int a, int b) {
        return a / b;  // throws ArithmeticException if b == 0
    }

    public static void main(String[] args) {
        // Basic try-catch
        try {
            int result = divide(10, 2);
            System.out.println("10 / 2 = " + result);

            int bad = divide(5, 0);  // throws ArithmeticException
            System.out.println("This line never runs");
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
        } finally {
            System.out.println("finally always runs");
        }

        // Catching multiple exception types separately
        String[] names = {"Alice", "Bob"};
        try {
            System.out.println(names[5]);          // ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Index error: " + e.getMessage());
        } catch (Exception e) {
            // General catch — must come AFTER specific ones
            System.out.println("General error: " + e.getMessage());
        }

        // NumberFormatException (unchecked)
        try {
            int n = Integer.parseInt("abc");
        } catch (NumberFormatException e) {
            System.out.println("Parse error: " + e.getMessage());
        }
    }
}

ArithmeticException is unchecked (extends RuntimeException) so no throws declaration is needed. The finally block always executes — even when an exception is caught.

Multi-catch and throwjava
public class MultiCatchDemo {

    // throws declares a checked exception callers must handle
    public static String readConfig(String key) throws java.io.IOException {
        if (key == null) {
            throw new IllegalArgumentException("key must not be null");
        }
        if (key.isEmpty()) {
            throw new java.io.IOException("Cannot read config: empty key");
        }
        return "value-" + key;
    }

    public static void parseAndPrint(String input) {
        try {
            // Two different unchecked exceptions — handled identically
            int value = Integer.parseInt(input);   // NumberFormatException
            int[] arr  = new int[value];
            System.out.println(arr[value + 1]);    // ArrayIndexOutOfBoundsException
        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
            // Multi-catch: e is implicitly final here
            System.out.println("Caught (" + e.getClass().getSimpleName() + "): " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        // Must handle checked IOException
        try {
            System.out.println(readConfig("host"));
            System.out.println(readConfig(""));     // triggers IOException
        } catch (java.io.IOException e) {
            System.out.println("IO problem: " + e.getMessage());
        }

        // Unchecked — no try required, but we demonstrate multi-catch
        parseAndPrint("abc");       // NumberFormatException path
        parseAndPrint("3");         // ArrayIndexOutOfBoundsException path
    }
}

Multi-catch (A | B e) avoids duplicating catch bodies. The throws keyword on readConfig forces every caller to either catch IOException or propagate it further.

Checked exceptions with throws declarationjava
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class CheckedDemo {

    // Declares checked IOException — callers must deal with it
    public static String loadFile(Path path) throws IOException {
        if (!Files.exists(path)) {
            throw new IOException("File not found: " + path);
        }
        return Files.readString(path);
    }

    // Wraps loadFile and handles the checked exception locally
    public static String safeLoad(Path path) {
        try {
            return loadFile(path);
        } catch (IOException e) {
            // Log and return a safe default instead of crashing
            System.err.println("Warning: " + e.getMessage());
            return "";
        }
    }

    public static void main(String[] args) {
        Path missing = Path.of("nonexistent.txt");

        // Option 1: handle at call site
        try {
            String content = loadFile(missing);
            System.out.println(content);
        } catch (IOException e) {
            System.out.println("Handled at main: " + e.getMessage());
        }

        // Option 2: use the wrapper that handles internally
        String result = safeLoad(missing);
        System.out.println("Safe result: '" + result + "'");

        // Stack trace details
        try {
            throw new IOException("demo error");
        } catch (IOException e) {
            System.out.println("Class : " + e.getClass().getName());
            System.out.println("Msg   : " + e.getMessage());
            // e.printStackTrace() would print the full stack trace
        }
    }
}

Checked exceptions force callers to acknowledge failure paths at compile time. You can either handle them (try/catch) or propagate them (add throws to your own signature).

Quick Quiz

1. Which of these is a checked exception?

2. When does the finally block execute?

3. What is the correct order for multiple catch blocks?

4. What does the `throws` keyword on a method signature mean?

Was this lesson helpful?

PreviousNext