4.3 try-catch-finally Execution Flow
← Back to Chapter 4: Exception Handling
The try-catch-finally block is Java's foundational error handling construct. Understanding its detailed control flow guarantees that critical resources are never orphaned.
Execution Flow Rules
tryblock: Contains code that might throw an exception.catchblock: This block executes only if an exception matching the parameter type is thrown.finallyblock: This block always executes, whether an exception occurred, was caught, or was uncaught.
try {
processPayment();
} catch (InsufficientFundsException | ExpiredCardException e) {
// Multi-catch (Java 7+): parameter 'e' is implicitly final
log.warn("Payment failed: {}", e.getMessage());
} catch (PaymentGatewayException e) {
// Broader exception caught lower in the hierarchy
log.error("Gateway outage", e);
} finally {
releaseTransactionLock(); // Guaranteed cleanup!
}
Multiple Catch blocks
try {
// risky code
} catch (ArithmeticException e) {
// handle arithmetic problem
} catch (NullPointerException e) {
// handle null problem
} catch (Exception e) {
// handle other exceptions
}
Important rule
The more specific exception must come first.
In this case ArithmeticException and NullPointerException are more specific than Exception.
finally
finally is used for cleanup code.
try {
// risky operation
} catch (Exception e) {
// handle exception
} finally {
// cleanup
}
finally generally executes whether an exception occurs or not.
Can we have try without catch?
Yes.
try {
// code
} finally {
// cleanup
}
This is valid.
But this is not valid:
try {
// code
}
A try must be followed by at least:
catch
OR
finally
Can finally be skipped?
Normally, finally executes.
But there are exceptional situations, for example:
System.exit(0);
If the JVM terminates using System.exit(), normal finally execution does not occur.
Also, if the JVM itself crashes/terminates abnormally, there is no guarantee that finally will execute.
throw keyword
throw is used when you want to explicitly throw an exception. It is used inside the function.
Example:
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or above");
}
Think:
throw = actually throw an exception
throws
throws is used in a method declaration.
Example:
public void readFile() throws IOException {
// code
}
It means:
"This method may throw IOException. Whoever calls me needs to deal with it."
throw vs throws
| throw | throws |
|---|---|
| Used to actually throw exception | Declares possible exceptions |
| Used inside method/block | Used in method signature |
| Throws one exception at a time | Can declare multiple exceptions |
throw new Exception() | throws IOException |
throw = actually throw an exception
throws = declaring that this function may throw an exception