- Explain what an exception is and read a stack trace
- Use
try,catchandfinallyblocks - Tell checked from unchecked exceptions and write a custom exception class
The user typed “abc” instead of their age, a file was deleted, the internet went down — in real programs, not everything goes to plan. A good program does not “crash” in such situations; it reports the problem politely and keeps working. In Java, unexpected situations are handled with exceptions.
What is an exception?
An exception is an object that describes an event which breaks the normal flow of a program. When one happens, Java “throws” it: the current method stops at once, and the exception travels up the chain of calls until some code catches it. If nobody does, the program stops and prints a stack trace to the console.
public class Main {
public static void main(String[] args) {
int[] marks = {5, 4, 3};
System.out.println("Start");
System.out.println(marks[5]);
System.out.println("End");
}
}Start Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3 at Main.main(Main.java:5)
Read the stack trace from the top: first the exception's type (ArrayIndexOutOfBoundsException), then its message (index 5 is out of bounds for length 3), then where it happened — line 5 of Main.java. “End” was never printed: after an exception, the rest of the method does not run.
try, catch and finally
We put risky code in a try block. If an exception occurs, control jumps to the catch block of the matching type. The finally block runs in every case — whether an exception happened or not; it is usually used for clean-up work such as closing a file or a connection.
public class Main {
public static void main(String[] args) {
String[] inputs = {"42", "abc", "0"};
for (String input : inputs) {
try {
int n = Integer.parseInt(input);
System.out.println("100 / " + n + " = " + (100 / n));
} catch (NumberFormatException e) {
System.out.println("Not a number: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("Math error: " + e.getMessage());
} finally {
System.out.println("-- checked \"" + input + "\"");
}
}
}
}100 / 42 = 2 -- checked "42" Not a number: For input string: "abc" -- checked "abc" Math error: / by zero -- checked "0"
Integer.parseInt("abc")cannot turn the text into a number and throws aNumberFormatException.- Dividing an integer by zero causes an
ArithmeticException. (Interestingly,100.0 / 0throws nothing and givesInfinity.) e.getMessage()returns the exception's message. The program did not stop after an exception — the loop went on with the next value.finallyran in all three cases.
Checked and unchecked exceptions
The common parent of all exceptions is Throwable. From it come Error (serious JVM problems such as running out of memory — usually not caught) and Exception. Exception has a special branch — RuntimeException. This split defines a rule that is unique to Java:
| Feature | Checked | Unchecked |
|---|---|---|
| Inherits from | Exception (but not RuntimeException) | RuntimeException |
| Does the compiler insist? | yes: catch it or declare it with throws | no |
| Usually means | a problem outside the program's control | a programming mistake |
| Examples | IOException, FileNotFoundException | NullPointerException, ArithmeticException, IllegalArgumentException |
For example, if you write new FileReader("data.txt") without wrapping it in try, the code will not compile: unreported exception FileNotFoundException; must be caught or declared to be thrown. The compiler is saying: “The file might not exist — decide in advance what to do then.”
throw, throws and your own exceptions
You can throw an exception yourself: throw new IllegalArgumentException("..."). This is the best way to stop a method from accepting bad data. To create your own exception class, extend Exception (checked) or RuntimeException (unchecked). A method that throws a checked exception must declare it in its header with throws.
public class Main {
static void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Invalid age: " + age);
}
System.out.println("Age set to " + age);
}
public static void main(String[] args) {
try {
setAge(25);
setAge(-3);
setAge(40);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("Program continues");
}
}Age set to 25 Error: Invalid age: -3 Program continues
setAge(40) was never called: as soon as setAge(-3) threw an exception, the try block stopped and control moved to catch. Now let's create our own checked exception — for when a wallet does not have enough money:
public class Main {
public static void main(String[] args) {
Wallet wallet = new Wallet(30);
try {
wallet.pay(12);
wallet.pay(25);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
System.out.println("Missing: " + e.getMissing() + " AZN");
}
}
}
class InsufficientFundsException extends Exception {
private final double missing;
InsufficientFundsException(double missing) {
super("Not enough money in the wallet");
this.missing = missing;
}
double getMissing() { return missing; }
}
class Wallet {
private double balance;
Wallet(double balance) { this.balance = balance; }
void pay(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount - balance);
}
balance -= amount;
System.out.println("Paid " + amount + ", left " + balance);
}
}Paid 12.0, left 18.0 Not enough money in the wallet Missing: 7.0 AZN
Key points
- An exception is an event that breaks the normal flow; if it is not caught, the program stops and prints a stack trace.
tryholds risky code,catchcatches a specific exception type, andfinallyalways runs.- Checked exceptions (
IOException) must be caught or declared withthrows;RuntimeExceptionsubclasses are unchecked. throw new ...throws an exception; for your own exception, extendExceptionorRuntimeException.- Never write an empty
catchblock — the information about the error is lost.
Check yourself
10 questions. Every correct answer earns XP.
finally block run?