Java Exceptions: try, catch, finally and throw
An exception is an error which happens while the program is running, like dividing by zero or opening a file which does not exist. If you do not handle it, the program stops. With exception handling, you catch the problem and decide what to do.
try and catch
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero: " + e.getMessage());
}
System.out.println("The program goes on");
}
}
Cannot divide by zero: / by zero
The program goes on
Many catch blocks
Java uses the first catch which matches. Put the more special exceptions first.
public class Multi {
static void test(String text, int index) {
try {
int n = Integer.parseInt(text);
int[] a = new int[3];
a[index] = n;
System.out.println("Saved " + n);
} catch (NumberFormatException e) {
System.out.println("Not a number: " + text);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Bad index: " + index);
} catch (Exception e) {
System.out.println("Something else: " + e);
}
}
public static void main(String[] args) {
test("5", 1);
test("abc", 1);
test("5", 9);
}
}
Saved 5
Not a number: abc
Bad index: 9
You can catch two types in one block with catch (A | B e).
finally
The finally block runs always, with or without an exception. It is used for cleaning, like closing a file.
public class Fin {
static int test(boolean fail) {
try {
if (fail) throw new RuntimeException("boom");
return 1;
} catch (RuntimeException e) {
System.out.println("caught " + e.getMessage());
return 2;
} finally {
System.out.println("finally runs");
}
}
public static void main(String[] args) {
System.out.println(test(false));
System.out.println(test(true));
}
}
finally runs
1
caught boom
finally runs
2
Checked and unchecked exceptions
| Type | Parent | Rule | Example |
|---|---|---|---|
| Checked | Exception (not Runtime) | The compiler forces you to catch or declare it | IOException |
| Unchecked | RuntimeException | No force. Usually a bug in the code | NullPointerException |
| Error | Error | Serious JVM problems. Do not catch | OutOfMemoryError |
throw and throws
throw creates an exception. throws in the method line says that the method can throw a checked exception.
import java.io.IOException;
public class Throw {
static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or more");
}
System.out.println("Access granted");
}
static void readFile() throws IOException {
throw new IOException("File not found");
}
public static void main(String[] args) {
try {
checkAge(20);
checkAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
try {
readFile();
} catch (IOException e) {
System.out.println("IO problem: " + e.getMessage());
}
}
}
Access granted
Error: Age must be 18 or more
IO problem: File not found
If you call a method which throws a checked exception and do not handle it, the code does not compile:
import java.io.IOException;
public class Checked {
static void risky() throws IOException {
throw new IOException("bad");
}
public static void main(String[] args) {
risky();
}
}
Checked.java:9: error: unreported exception IOException; must be caught or declared to be thrown
risky();
^
1 error
error: compilation failed
Custom exceptions
class InsufficientFundsException extends Exception {
private final double shortBy;
InsufficientFundsException(String message, double shortBy) {
super(message);
this.shortBy = shortBy;
}
double getShortBy() {
return shortBy;
}
}
public class Custom {
static void withdraw(double balance, double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Not enough money", amount - balance);
}
System.out.println("Withdrawn " + amount);
}
public static void main(String[] args) {
try {
withdraw(500, 200);
withdraw(500, 800);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage() + ", short by " + e.getShortBy());
}
}
}
Withdrawn 200.0
Not enough money, short by 300.0
try with resources
A resource (like a file or a connection) that implements AutoCloseable is closed by itself at the end of the try, even if there is an error.
public class Res {
static class Door implements AutoCloseable {
Door(String name) { System.out.println("open " + name); }
void use() { System.out.println("using"); throw new IllegalStateException("oops"); }
@Override public void close() { System.out.println("closed"); }
}
public static void main(String[] args) {
try (Door d = new Door("front")) {
d.use();
} catch (IllegalStateException e) {
System.out.println("caught " + e.getMessage());
}
}
}
open front
using
closed
caught oops
Good practices
- Catch the most specific exception you can. Do not use an empty catch block.
- Do not use exceptions for normal flow (like ending a loop).
- Use
try with resourcesfor files, sockets and database connections. - Write a helpful message that tells what went wrong and which value was bad.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |