Advanced Java
Exception Handling
Complete lesson for Exception Handling using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with Java OOP and Collections where relevant.
Basics — Exception Handling
Section: Advanced Java. try, catch, finally, throw, throws, checked vs unchecked, and try-with-resources.
The hierarchy
Throwable→Error(JVM disasters:OutOfMemoryError,StackOverflowError) andException.RuntimeException(and its children:NullPointerException,IllegalArgumentException,IndexOutOfBoundsException) are **unchecked**.- Other
Exceptions (IOException,SQLException,ClassNotFoundException) are **checked** —javacforces you to catch or declare them.
| Kind | Examples | Must declare / catch? |
|---|---|---|
| Checked | IOException, InterruptedException | Yes |
Unchecked (RuntimeException) | NPE, IAE, ClassCastException | No |
| Error | OutOfMemoryError | No (do not catch routinely) |
try, catch, finally, throw, throws
tryprotects statements.catch (Type ex)handles that type or a subclass. Multiple catch blocks go from **specific to general**.finallyalways runs (except JVM death /System.exit). Use it for cleanup, or prefer try-with-resources.throwraises an exception object.throwson a method advertises checked exceptions callers must handle.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ExceptionBasics {
static String read(Path path) throws IOException {
return Files.readString(path);
}
public static void main(String[] args) {
try {
System.out.println(read(Path.of("missing.txt")));
} catch (IOException e) {
System.out.println("checked: " + e.getClass().getSimpleName());
} finally {
System.out.println("done");
}
}
} throw vs throws
| Keyword | Where | Meaning |
|---|---|---|
throw | Inside a body | Actually throw this object |
throws | Method signature | This method may pass that checked exception out |
Advanced — Exception Handling
Multi-catch, suppressed exceptions, and design
catch (IOException | SQLException e)(Java 7) —eis effectively final.- try-with-resources: if
close()throws too, that exception is *suppressed* and attached to the primary one (getSuppressed()). - Do not catch
Exceptionunless you rethrow or log at a boundary. Emptycatch (Exception e) {}hides bugs. - Create custom exceptions as checked only when the caller can reasonably recover; otherwise extend
RuntimeException. - Java does not have C++ destructor unwind for arbitrary objects — use try-with-resources /
finally.
Tricky Interview Points
Q1) Checked vs unchecked exceptions?
Answer Checked (Exception minus RuntimeException) must be caught or declared. Unchecked (RuntimeException and Error) need not. Use checked for recoverable environmental failures; unchecked for programming bugs.
Q2) throw vs throws?
Answer throw creates/raises an exception. throws lists checked exceptions a method might propagate.
Q3) Does finally run after return?
Answer Yes. If finally also returns or throws, it overrides the original return/exception. Avoid return in finally.
Q4) Can you catch Error?
Answer Syntactically yes, practically no. Errors mean the JVM is in trouble. Do not write recovery logic for OOME as if it were IOException.
Q5) What is try-with-resources?
Answer try (Resource r = ...) { } auto-closes AutoCloseable resources. Preferred over manual finally close.
Q6) Can a constructor throw?
Answer Yes. If it throws, new fails and the reference is never assigned. Declare checked exceptions on the constructor.
Q7) What is exception chaining?
Answer new ServiceException("save failed", cause) keeps the original stack via getCause(). Always pass the cause when you wrap.
Simple Programs
Custom unchecked exception and multi-catch
class InvalidAgeException extends RuntimeException {
InvalidAgeException(String message) {
super(message);
}
}
public class AgeCheck {
static void register(int age) {
if (age < 0 || age > 130) {
throw new InvalidAgeException("age=" + age);
}
System.out.println("ok " + age);
}
public static void main(String[] args) {
try {
register(200);
} catch (InvalidAgeException | IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
} Problem Solving Tricks
- Catch the most specific type first.
- Wrap low-level exceptions with a domain exception *and* the cause.
- Never use exceptions for normal control flow (e.g.
parseIntin a loop instead of a regex/guard). - Log once at the boundary; do not log-and-rethrow at every layer.
InterruptedExceptionis special: restore the interrupt flag if you cannot throw it (Thread.currentThread().interrupt()).
Practice Programs List
- Write a method that parses an int and catches
NumberFormatException. - Propagate
IOExceptionwiththrowsfrom a helper tomain. - Show that
finallyprints even when youreturninsidetry. - Create a checked
InsufficientFundsExceptionand force the caller to handle it. - Open two closeable resources in one try-with-resources.