Skip to content

Intermediate · Exceptions and generics · topic 27 of 60 · 25 min

Checked vs unchecked exceptions and throwing your own

Explanation

Checked exceptions (like IOException) must be caught or declared with throws, so the compiler forces callers to think about them. Unchecked exceptions (RuntimeException and its subclasses) usually signal bugs or bad input and need no declaration. You raise your own with throw new …, create custom exception classes for domain problems, and wrap low-level exceptions with a cause.

Checked exceptions

Some failures are expected in normal operation and the caller should decide what to do: a file may not exist, a network may be down, a database may refuse a query. For these, Java uses checked exceptions (subclasses of Exception but not of RuntimeException). The compiler checks that every checked exception is either caught or declared in the method's throws clause.

java
import java.io.IOException;
import java.nio.file.*;

static String readConfig(String path) throws IOException {   // declared: callers must deal with it
    return Files.readString(Path.of(path));
}

public static void main(String[] args) {
    try {
        System.out.println(readConfig("app.properties"));
    } catch (IOException e) {
        System.out.println("Could not read config: " + e.getMessage());
    }
}
// Calling readConfig without try/catch or throws → compile error: unreported exception IOException

Unchecked exceptions

Unchecked exceptions extend RuntimeException. They usually mean a programming error or invalid arguments: NullPointerException, IllegalArgumentException, IllegalStateException, ArithmeticException, IndexOutOfBoundsException. The compiler does not force you to handle them; the fix is usually to correct the code or validate the input.

Throwing your own

java
public void withdraw(double amount) {
    if (amount <= 0) throw new IllegalArgumentException("Amount must be positive: " + amount);
    if (amount > balance) throw new IllegalStateException("Insufficient balance");
    balance -= amount;
}
throw (no s) raises an exception; throws (with s) declares one in a method signature.

Custom exception classes

java
public class InsufficientBalanceException extends RuntimeException {
    private final double shortBy;
    public InsufficientBalanceException(double shortBy) {
        super(String.format("Insufficient balance: short by Rs %.2f", shortBy));
        this.shortBy = shortBy;
    }
    public double getShortBy() { return shortBy; }
}

// throw new InsufficientBalanceException(amount - balance);

A custom exception gives callers a precise type to catch and extra data (shortBy). Extend RuntimeException for problems callers usually cannot recover from or that indicate misuse; extend Exception (checked) when callers are expected to handle it. Many modern libraries and frameworks, including Spring, prefer unchecked exceptions.

Wrapping with a cause

java
try {
    loadRatesFromFile();
} catch (IOException e) {
    throw new IllegalStateException("Could not load GST rates", e);   // keep the original as the cause
}
The stack trace will show "Caused by: java.io.IOException …", so the root problem is not lost.
Careful: Common mistakes: throwing a generic Exception or RuntimeException with no message; catching and re-throwing without the cause (the original stack trace is lost); declaring throws Exception on every method; and using exceptions for normal control flow (like ending a loop). Exceptions are for exceptional situations.
Think of it like this: A checked exception is like a courier package marked "signature required": the receiver must sign (catch) or formally pass it on (throws). An unchecked exception is like a fire alarm: nobody signs for it in advance, but when it rings, something is really wrong and must be fixed.
Tip: Fail fast: validate arguments at the start of public methods and throw IllegalArgumentException with a message that names the bad value. A clear error at the entrance is much easier to debug than a strange result much later.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Checked vs unchecked exceptions and throwing your own · 1/6

Checked vs unchecked

In this lesson you will meet checked and unchecked exceptions and throw your own.

Prefer a video by a teacher? Find free videos on “java checked vs unchecked exceptions custom exception throw throws” on YouTube ↗

In real life: A train booking service

A booking service throws custom unchecked exceptions such as NoSeatsAvailableException and InvalidPassengerException. The REST layer catches them and turns each into the right HTTP response (409 Conflict, 400 Bad Request), while unexpected exceptions become 500 errors and are logged with their causes.

java
class NoSeatsAvailableException extends RuntimeException {
    NoSeatsAvailableException(String train, String date) {
        super("No seats on " + train + " for " + date);
    }
}
// in the service: if (available == 0) throw new NoSeatsAvailableException("12951", "2026-11-05");

Practice (0/3 done)

Task 1 · Question

Which is a CHECKED exception?

Task 2 · Question

static void load() { Files.readString(Path.of("a.txt")); } Why does this not compile?

Task 3 · Code · Javascript

The same idea in JavaScript, which runs here: write a class InsufficientBalanceError extends Error with a shortBy property, and withdraw(balance, amount) that throws a RangeError "Amount must be positive" for amount <= 0, throws InsufficientBalanceError (message "Insufficient balance") when amount > balance, and otherwise returns the new balance.

Quick quiz

Question 1

1.What is the difference between throw and throws?

Question 2

2.Which base class makes a custom exception unchecked?

Question 3

3.Why pass the original exception as a cause when wrapping?

Question 4

4.Which is a good message for an exception?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is the difference between throw and throws?

Answer: throw raises an exception; throws declares that a method may throw

One is a statement, the other part of a signature.

Which base class makes a custom exception unchecked?

Answer: RuntimeException

RuntimeException subclasses are unchecked.

Why pass the original exception as a cause when wrapping?

Answer: So the root problem and its stack trace are not lost

Caused by: lines keep the full story.

Which is a good message for an exception?

Answer: "Invalid PIN code: 0400012 (must be 6 digits)"

Say what failed and with which value.

A custom exception class should inherit from...Related

Answer: Exception

Custom exceptions derive from Exception (or a more specific exception).

From Exceptions: try, catch, finally and custom exceptions

Which base class should your own exception types usually derive from?Related

Answer: std::exception (often via std::runtime_error)

Then generic handlers for std::exception catch them too, and what() works.

From Exceptions: throw, try, catch and noexcept

null.length throws which error?Related

Answer: TypeError

Reading a property of null is a TypeError.

From Error handling: try, catch, finally and throw

What happens to an exception nobody catches in main?Related

Answer: The thread ends and the stack trace is printed

Uncaught exceptions end the thread.

From Exceptions: try, catch and finally

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Exceptions and generics” before its exam: try-with-resources and clean-up, Generics, Avoiding NullPointerException.
  2. Module 6 exam: Exceptions and generics · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, The collections framework. 60 topics left in the course before the final exam.

← Previous: Exceptions: try, catch and finally