Reading — step 1 of 7
Learn
Real programs encounter errors — invalid input, missing files, network failures, division by zero. Java's exception handling lets you signal failures via the type system and respond to them in dedicated paths. Oracle's Java Tutorials chapter 11 treats this as essential.
try / catch / finally
try {
int n = Integer.parseInt(input);
int result = 100 / n;
System.out.println("result: " + result);
} catch (NumberFormatException e) {
System.out.println("not a valid number: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("can't divide by zero");
} finally {
System.out.println("cleanup");
}
tryblock — code that might throwcatchblocks — handle specific exception types (multiple OK, ordered most-specific to least)finallyblock — always runs, even if exception was thrown or caught. For cleanup.
throw — signal a problem
public int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("divide by zero");
}
return a / b;
}
The throw statement creates and propagates an exception. Until something catches it (or the program crashes).
throws — declare a method might throw
public String readFile(String path) throws IOException {
return Files.readString(Paths.get(path));
}
Checked exceptions (subclasses of Exception but not RuntimeException) MUST be either caught or declared with throws in the method signature. The compiler enforces this.
Unchecked exceptions (subclasses of RuntimeException) don't require declaration — programmer errors like NPE, array out-of-bounds, illegal arguments.
The hierarchy
Throwable
├── Error (JVM-level — don't catch)
└── Exception
├── RuntimeException (UNCHECKED)
│ ├── NullPointerException
│ ├── IllegalArgumentException
│ ├── ArithmeticException
│ └── IndexOutOfBoundsException
└── (other Exception) (CHECKED — must declare or catch)
├── IOException
├── SQLException
└── ...
Catch the specific type you intend to handle. Catching Exception (or worse, Throwable) hides bugs.
Multi-catch (Java 7+)
try { ... }
catch (IOException | SQLException e) {
log("data layer failed: " + e.getMessage());
}
Handle multiple exception types in one block when the response is the same.
try-with-resources (Java 7+)
For anything that implements AutoCloseable (Stream, BufferedReader, Connection):
try (BufferedReader br = Files.newBufferedReader(Paths.get("data.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} // br.close() automatically — even if exception thrown
Replaces the old try/finally close() pattern. Always use it for resources.
Custom exceptions
public class ValidationException extends Exception {
private final String field;
public ValidationException(String field, String message) {
super(message);
this.field = field;
}
public String getField() { return field; }
}
throw new ValidationException("email", "invalid format");
Extend RuntimeException for unchecked, Exception for checked. Use checked when the caller MUST handle the failure; unchecked for programmer errors.
Common mistakes
- Catching
Exceptionto silence errors — hides bugs. Catch the specific type you can handle. - Empty catch blocks —
catch (Exception e) {}is the worst pattern in Java. At least log it. - Not closing resources — leaks file handles, connections. Use try-with-resources.
- Wrapping everything in try-catch "just in case" — if you can't meaningfully handle it, let it propagate to a higher-level handler.
- Using exceptions for control flow — exceptions are slow and confusing for normal cases. Use them for actual exceptional cases.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…