Unit 3 · Lesson 314 minAcademic review pending

When Java's own exceptions are not specific enough

Java ships common exceptions for common mistakes. When your program has a failure specific to its own domain — invalid marks, insufficient funds — you define that exception yourself, in a few lines.

Choose explanation

After this lesson

You should be able to

  • Name at least three built-in exception classes and what triggers each.
  • Write a custom checked exception class.
  • Explain why a custom exception often carries more useful information than a generic one.
01

The built-in exceptions you will meet constantly

ArithmeticException fires on integer division by zero, the exact bug CS105ES warned about, now surfaced as a catchable object instead of undefined behaviour. ArrayIndexOutOfBoundsException fires when an array index is out of range — recall this from CS303PC's own array lesson. NullPointerException fires when you call a method on a reference that points at nothing. NumberFormatException fires when code tries to parse text like "abc" as a number.

These four alone cover a large share of the errors you will actually hit while writing Java. Recognising which one you are looking at from its name is the first step to fixing it — the class name itself tells you what went wrong, unlike C's generic segmentation fault message.

02

Writing your own: a few lines, real payoff

A custom exception is a class that extends Exception (checked) or RuntimeException (unchecked), usually adding nothing beyond a constructor that forwards a message to the parent using super. The value is not in complex new code — it is in the name: catch (InvalidMarksException e) documents exactly what went wrong far better than a generic catch (Exception e) ever could.

A custom exception can also carry extra fields beyond a message — an InsufficientFundsException could store exactly how much was short, giving the catch block real data to act on, not just a printable string. This is a class doing what classes do best: bundling data with the context it needs.

A named failure, sometimes carrying its own data
class InvalidMarksException extends Exception {
    public InvalidMarksException(String message) {
        super(message);
    }
}

class InsufficientFundsException extends Exception {
    private double shortBy;

    public InsufficientFundsException(String message, double shortBy) {
        super(message);
        this.shortBy = shortBy;
    }

    public double getShortBy() {
        return shortBy;
    }
}

Try it yourself

Write a custom checked exception NegativeDepositException. Write a deposit(double amount) method that throws it when amount is negative, and catch it in calling code, printing the exception's message.

Need a hint?

The exception class itself needs almost no code — a constructor that calls super(message) is usually enough.

Check the worked solution

This mirrors InvalidMarksException exactly: a two-line exception class, a method that throws it under a specific condition, and a catch block that reads e.getMessage() to report what went wrong. Once you have written one custom exception, every future one follows the identical shape.

class NegativeDepositException extends Exception {
    public NegativeDepositException(String message) {
        super(message);
    }
}

static void deposit(double amount) throws NegativeDepositException {
    if (amount < 0) {
        throw new NegativeDepositException("Deposit cannot be negative");
    }
    System.out.println("Deposited: " + amount);
}

try {
    deposit(-50);
} catch (NegativeDepositException e) {
    System.out.println(e.getMessage());
}

Quick check

What does a custom exception like InvalidMarksException usually add beyond what a generic Exception already provides?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

built in exceptions, creating own exception subclasses.

Maps to course outcome CO1.