CodeMIRAI
0 XP

Exceptions

3 min read 6 runnable examples Quiz included

An exception is how Java reports that something went wrong while the program was running: an index past the end of an array, a number that isn't a number, a file that doesn't exist.

Java
public class Main {
    public static void main(String[] args) {
        int[] data = {10, 20, 30};
        System.out.println("Before");
        System.out.println(data[5]);
        System.out.println("After");      // never reached
    }
}

Read the stack trace from the top: the exception's type and message, then lines like at Main.main(Main.java:5), which say where it happened. The program stopped at line 5, so "After" never printed.

try and catch

Java
public class Main {
    public static void main(String[] args) {
        String[] inputs = {"42", "seven", "12"};
        int total = 0;
        for (String s : inputs) {
            try {
                total += Integer.parseInt(s);
            } catch (NumberFormatException e) {
                System.out.println("Skipping '" + s + "': not a number");
            }
        }
        System.out.println("Total: " + total);
    }
}

When code inside try throws, Java jumps straight to the matching catch, and the program carries on after it instead of crashing.

Several catches, and finally

Java
public class Main {
    static int divide(String a, String b) {
        try {
            return Integer.parseInt(a) / Integer.parseInt(b);
        } catch (NumberFormatException e) {
            System.out.println("Bad number: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Maths error: " + e.getMessage());
        } finally {
            System.out.println("(finished " + a + " / " + b + ")");
        }
        return 0;
    }

    public static void main(String[] args) {
        System.out.println(divide("10", "2"));
        System.out.println(divide("10", "zero"));
        System.out.println(divide("10", "0"));
    }
}

Each catch handles one kind of exception. The finally block runs whether or not anything went wrong, even after a return, which makes it the place for clean-up.

Throwing exceptions

Java
public class Main {
    static void setAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age can't be negative: " + age);
        }
        System.out.println("Age set to " + age);
    }

    public static void main(String[] args) {
        setAge(21);
        try {
            setAge(-3);
        } catch (IllegalArgumentException e) {
            System.out.println("Caught: " + e.getMessage());
        }
    }
}

throw raises an exception yourself, when a method is given something it can't work with.

Checked and unchecked

UncheckedChecked
extendsRuntimeExceptionException
examplesNullPointerException, IllegalArgumentException, ArithmeticExceptionIOException, FileNotFoundException
the compilerlets you ignore theminsists you catch them or declare them with throws
usually meansa bug in the programa problem outside the program's control
ThrowableErrorExceptionRuntimeExceptionIOExceptionNullPointerExceptionArithmeticExceptionserious problems:don't catchchecked: you mustcatch or declareunchecked: RuntimeException and its subclasses don't have to be declared
Checked exceptions such as IOException must be caught or declared with throws; RuntimeExceptions signal bugs and don't.
Java
void loadSettings() throws IOException {    // callers must now handle IOException
    ...
}

An exception of your own

Java
class InsufficientFundsException extends Exception {
    InsufficientFundsException(String message) {
        super(message);
    }
}

class Account {
    private double balance = 100;

    void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException("Balance is " + balance + ", tried to take " + amount);
        }
        balance -= amount;
    }
}

public class Main {
    public static void main(String[] args) {
        Account acct = new Account();
        try {
            acct.withdraw(30);
            acct.withdraw(500);
        } catch (InsufficientFundsException e) {
            System.out.println("Refused: " + e.getMessage());
        }
    }
}

Because it extends Exception, it's a checked exception: the compiler makes every caller of withdraw decide what to do when the money runs out.

try-with-resources

Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

public class Main {
    public static void main(String[] args) {
        String file = "line one\nline two\nline three";
        try (BufferedReader reader = new BufferedReader(new StringReader(file))) {
            String line;
            int n = 1;
            while ((line = reader.readLine()) != null) {
                System.out.println(n++ + ": " + line);
            }
        } catch (IOException e) {
            System.out.println("Could not read: " + e.getMessage());
        }
    }
}

Anything opened in the brackets after try, such as a file, a network connection or a database connection, is closed automatically at the end, even if an exception is thrown. (A StringReader stands in for a real file here, because the code runner has no files to read.)

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.