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.
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.
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.
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.
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?
Why this lesson exists
Syllabus mapping
built in exceptions, creating own exception subclasses.
Maps to course outcome CO1.