Java Exceptions
Java exceptions are objects that signal something went wrong while a program runs, such as dividing by zero or reading a missing file. Exception handling lets you respond to the problem instead of letting the program crash.
try and catch
Put risky code in a try block. If an exception is thrown, Java jumps to the matching catch block. finally always runs, whether or not an exception occurred, which is useful for cleanup.
public class Main {
public static void main(String[] args) {
String[] inputs = {"42", "abc"};
for (String in : inputs) {
try {
int n = Integer.parseInt(in);
System.out.println("100 / n = " + (100 / n));
} catch (NumberFormatException e) {
System.out.println("Not a number: " + in);
} finally {
System.out.println("Checked " + in);
}
}
}
}100 / n = 2 Checked 42 Not a number: abc Checked abc
Catching Several Exceptions
A single catch can handle several types with |. Catch specific exceptions rather than the general Exception whenever you can.
public class Main {
public static void main(String[] args) {
int[] data = {10, 0};
try {
System.out.println(data[0] / data[1]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("Problem: " + e.getMessage());
}
}
}Problem: / by zero
Checked vs Unchecked Exceptions
- Checked exceptions (like IOException) extend Exception; the compiler forces you to catch them or declare them with throws.
- Unchecked exceptions (like NullPointerException, IllegalArgumentException) extend RuntimeException and usually indicate programming bugs.
- Errors (like OutOfMemoryError) are serious JVM problems you normally should not catch.
throw, throws and Custom Exceptions
throw raises an exception. throws in a method signature warns callers that a checked exception may come out. You can create your own exception class by extending Exception or RuntimeException.
class InsufficientFundsException extends Exception {
InsufficientFundsException(String message) { super(message); }
}
public class Main {
static double withdraw(double balance, double amount) throws InsufficientFundsException {
if (amount <= 0) throw new IllegalArgumentException("Amount must be positive");
if (amount > balance) {
throw new InsufficientFundsException("Need " + (amount - balance) + " more");
}
return balance - amount;
}
public static void main(String[] args) {
try {
System.out.println(withdraw(100, 30));
System.out.println(withdraw(100, 250));
} catch (InsufficientFundsException e) {
System.out.println("Declined: " + e.getMessage());
}
}
}70.0 Declined: Need 150.0 more
try-with-resources
Resources such as files and database connections must be closed. Declare them in parentheses after try and Java closes them automatically, even when an exception happens.
class Connection implements AutoCloseable {
Connection() { System.out.println("Opened"); }
void query() { System.out.println("Querying"); }
@Override public void close() { System.out.println("Closed"); }
}
public class Main {
public static void main(String[] args) {
try (var conn = new Connection()) {
conn.query();
}
}
}Opened Querying Closed
Frequently asked questions
What is the difference between throw and throws in Java?
throw is a statement that actually raises an exception object. throws is part of a method declaration that lists the checked exceptions the method might pass to its caller.
Should I catch Exception in Java?
Usually not. Catching the broad Exception type hides bugs. Catch the specific exceptions you can actually handle, and let others propagate.
Does finally always run in Java?
Almost always: it runs after try or catch even if they return. It is skipped only if the JVM exits, for example via System.exit, or crashes.
How do I avoid NullPointerException?
Check for null before using references, initialise fields in constructors, use Objects.requireNonNull for parameters, and consider Optional for values that may be absent.