Exceptions are Java's mechanism for dealing with things going wrong at runtime - a missing file, invalid input, a network call that fails - without crashing the whole program.
try / catch / finally
try {
int result = 10 / 0; // throws ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Can't divide by zero: " + e.getMessage());
} finally {
System.out.println("This always runs, error or not");
}
Checked vs unchecked exceptions
Checked exceptions (like IOException) must be either caught or declared with throws - the compiler enforces this. Unchecked exceptions (like NullPointerException, ArithmeticException) do not require this - they usually represent programming bugs rather than expected failure conditions.
public void readFile(String path) throws IOException {
// method that might throw a checked exception must declare it
}
Throwing your own exceptions
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
this.age = age;
}
Custom exception classes
For domain-specific errors, define your own exception by extending Exception (checked) or RuntimeException (unchecked):
public class InsufficientBalanceException extends RuntimeException {
public InsufficientBalanceException(String message) {
super(message);
}
}
// usage:
if (balance < amount) {
throw new InsufficientBalanceException("Not enough funds");
}
Catch specific exception types, not a blanket catch (Exception e), whenever you can - it keeps you from accidentally swallowing bugs you did not anticipate.