Skip to main content

Section 7.2 Standard Library Exceptions

Subsection 7.2.1 Preventing a Bill-Splitting Crash

Imagine youโ€™re writing a program to split a restaurant bill among friends:
Running this code will throw an ArithmeticException, because dividing by zero is undefined. This runtime crash could surprise you (or your users).
So how can you prevent it?
  • Option 1 (Manual Check): Before dividing, do if (numberOfPeople == 0) { /* handle error */ }. This way, you ensure no crash occurs.
  • Option 2 (Exceptions): If you forget the check, Java automatically throws ArithmeticException. But itโ€™s an unchecked exception, so the compiler doesnโ€™t force you to handle it.
This raises a question: Why does Java sometimes force you to handle errors, and other times let them slip by until runtime? Thatโ€™s exactly what weโ€™ll explore now.

Subsection 7.2.2 Categories of Java Exceptions

In Java, when something goes wrong, the program can throw different types of exceptions. These fall into three main categories:
1. Errors
  • Category: Error
  • Purpose: Critical failures that affect the entire system. Not meant to be handled.
  • Examples: OutOfMemoryError, StackOverflowError
  • Do You Handle It? โŒ No, usually unfixable.
2. Checked Exceptions
  • Category: Checked Exception
  • Purpose: Recoverable failures that Java forces you to either handle (try/catch) or declare (throws).
  • Examples: IOException, ClassNotFoundException
  • Do You Handle It? โš ๏ธ Required: Either (try/catch) OR (throws).
3. Unchecked Exceptions
  • Category: Unchecked Exception
  • Purpose: Programmer mistakes that cause a crash at runtime.
  • Examples: ArithmeticException, NullPointerException
  • Do You Handle It? ๐Ÿ”ถ You can handle them, but Java doesnโ€™t force you to.
All of these categories belong to a broader group called Throwable. Java splits these into two main groups:
  • Errors like OutOfMemoryError indicate system-level failures. You almost never handle them directlyโ€”if your program runs out of memory, thereโ€™s often little you can do.
  • Exceptions represent problems you can handle in code. They come in two types:
    • Checked Exceptions: The compiler forces you to either catch them or declare them with throws. Example: IOException.
    • Unchecked Exceptions: The compiler does not require explicit handling. Example: ArithmeticException, NullPointerException.

Subsection 7.2.3 Which Should the Compiler Force Us to Handle?

Letโ€™s test your understanding. Pause here! Write down your answers before continuing.
Question 1: Handling IOException (Checked)
Suppose a method needs to read data. The data might be invalid or missing. Should Java:
A) Force you to handle or declare IOException before running
B) Assume youโ€™ll remember to check manually
Question 2: Handling ArithmeticException (Unchecked)
Suppose a method divides two numbers, and the divisor might be zero. Should Java:
A) Force the programmer to write try/catch around every division
B) Assume the programmer will fix or avoid dividing by zero
Think: What did you choose? Why?
Answers: For IOException, Java does (A)โ€”itโ€™s a checked exception. For ArithmeticException, Java does (B)โ€”itโ€™s unchecked, so youโ€™re not forced to handle it at compile time. Thatโ€™s the heart of checked vs. unchecked.

Subsection 7.2.4 Checked and Unchecked in Practice

Some failures, like a missing file or a network issue, are beyond our control. Java has a rule: if a method might fail in this way, it must warn whoever calls it. This is why we use throws IOExceptionโ€”itโ€™s Javaโ€™s way of saying:
โ€œHey, something might go wrong! You need to handle this before running the program.โ€
Below is a partial implementation showing one method that might throw a checked exception, and another that can cause an unchecked exception:
(Before we see the answers, try to predict: What should the method do if y == 0? What kind of exception would make sense for readData()?)
public class ExceptionDemoSkeleton {

    // Checked exception example
    public static void readData() throws ??? {
        // What checked exception might we throw here?
        // e.g., throw new ???("Unable to read data...");
    }

    // Unchecked exception example
    public static int safeDivide(int x, int y) {
        // What if y == 0?
        // Return x / y or do a manual check?
        return ???;
    }
}
Think: Which standard checked exception could you throw? (Hint: IOException is a typical example for "something went wrong reading data.") And what should you do for safeDivide if y == 0?
Compare your answers with the full code below:
Notice that the compiler demands we handle or declare IOException but doesnโ€™t require us to handle ArithmeticException. Thatโ€™s the essence of checked vs. unchecked exceptions in action.

Subsection 7.2.5 Why throw new Exception(...) Is Too Generic

Whatโ€™s wrong with this code? Before reading further, try to spot the mistake:
public static void setAge(int age) throws Exception {
    if (age < 0) {
        throw new Exception("Something went wrong!");
    }
    // ... proceed with setting age
}
This code compiles, but "Something went wrong!" doesnโ€™t clearly say what the error is. It also forces a generic Exception onto the caller.
Hereโ€™s a better approach using a more specific, built-in type:
public static void setAge(int age) {
    if (age < 0) {
        // IllegalArgumentException is unchecked, but communicates exactly what happened
        throw new IllegalArgumentException("Age cannot be negative.");
    }
    // ... proceed with setting age
}
Now itโ€™s clear to the caller that the argument was illegal. Specific exception types convey more meaning than a generic Exception.

Subsection 7.2.6 How to Handle Exceptions in Your Own Code

When You See a Checked Exception (IOException, SQLException):
  • The compiler wonโ€™t let you ignore it
  • You must use try/catch or declare throws
  • These usually mean something external went wrong (like a missing file)
When You Get an Unchecked Exception (NullPointerException, ArithmeticException):
  • These usually mean a bug in your code
  • Instead of catching them, fix the mistake that caused them
  • Common examples: dividing by zero, using null values
Best Practices for Your Code:
  • Never use throw new Exception(...)โ€”itโ€™s too vague
  • Choose specific exception types that clearly describe what went wrong
  • For dangerous operations (like division), check for invalid values first
  • When reading files or using networks, always handle checked exceptions
In Your Own Code, Remember:
  • Handle external failures (files, networks) using try/catch or throws
  • Avoid generic Exceptionโ€”use a specific type like IllegalArgumentException
  • For invalid input, check manually before proceeding (e.g., donโ€™t divide by zero)
  • If an error is a programmer mistake (like NullPointerException), fix the bug instead of catching it
Thatโ€™s the essence of working with Javaโ€™s standard exceptions. Next up, weโ€™ll continue exploring how to handle exceptions effectively (via try/catch and throws) so your programs never fail silentlyโ€”and your code remains clear and predictable.

Exercises 7.2.7 Exercises

1. Multiple-Choice: Errors vs. Exceptions.

Which statement best describes the difference between Java Error and Exception classes?
  • Error represents critical system-level failures (e.g., OutOfMemoryError) that are usually not handled, while Exception represents problems your code can potentially catch and recover from.
  • Exactly. Error is generally fatal for the JVM, whereas Exception is recoverable.
  • They have no difference at runtime; Error is just a deprecated name for Exception.
  • No. Error is a distinct hierarchy for system-level issues.
  • Any Error is a compile-time issue, while Exception is always a runtime-only class.
  • No. Both occur at runtime; Error is not a compile-time phenomenon.
  • Error is for user input mistakes, while Exception is strictly for developer errors in code logic.
  • No. User input mistakes typically lead to Exceptions; Error signals bigger issues (like memory exhaustion).

2. Multiple-Choice: Checked vs. Unchecked Exceptions.

Which of the following correctly compares checked vs. unchecked exceptions in Java?
  • Checked exceptions are only caused by arithmetic operations (like dividing by zero), while unchecked exceptions come from external issues (like missing files).
  • No. Itโ€™s actually the opposite: dividing by zero triggers an ArithmeticException, which is unchecked.
  • Java forces you to handle or declare unchecked exceptions, but not checked ones.
  • No. Itโ€™s reversed. Checked exceptions must be handled or declared; unchecked do not require that.
  • Checked exceptions (e.g., IOException) must be caught or declared using throws, while unchecked exceptions (e.g., ArithmeticException) donโ€™t require explicit handling.
  • Correct. Thatโ€™s the fundamental difference in how Java treats checked vs. unchecked.
  • They are identical in behavior, but checked exceptions only happen at compile-time and unchecked happen at runtime.
  • No. All exceptions occur at runtime; "checked" means the compiler enforces handling.

3. Multiple-Choice: Dividing By Zero.

You have a method int divide(int x, int y) that does return x / y;. What happens if y is zero?
  • The compiler will refuse to compile your code unless you catch ArithmeticException.
  • No. ArithmeticException is unchecked, so the compiler doesnโ€™t force you to catch it.
  • You automatically get a compile-time error, with no possibility of running the program.
  • No. Thereโ€™s no compile-time error for dividing by a variable that might be zero.
  • The method returns 0 by default if y is zero.
  • No. It throws ArithmeticException at runtime; no default zero return is provided.
  • The program throws ArithmeticException at runtime if y is zero, terminating unless you catch it or avoid the division.
  • Correct. Since ArithmeticException is unchecked, it occurs at runtime with no compile-time warnings.

4. Multiple-Choice: Generic Exception.

Why might throw new Exception("Something went wrong!") be discouraged compared to throwing a more specific exception type?
  • Generic Exception causes Java to skip the catch block entirely, making the program terminate immediately.
  • No. Java doesnโ€™t skip catch blocks if the type matches. The problem is lack of clarity.
  • Itโ€™s too vague. A more specific exception (e.g. IllegalArgumentException) conveys clearer intent, helping both the caller and any catch blocks respond appropriately.
  • Precisely. A specific exception type clarifies the exact nature of the error.
  • Throwing Exception is not valid Java code and wonโ€™t compile unless you add a final finally block.
  • No. It is valid code. The problem is that using a generic type is poor design, not compilation failure.
  • Itโ€™s not discouraged; in modern Java, Exception is always replaced automatically by RuntimeException at runtime.
  • No automatic replacement occurs. The developer must choose an appropriate type.
You have attempted of activities on this page.