If you have some cleanup code that needs to run regardless of whether an exception was thrown, try { ... } finally { ... }
is what you need. But what if you want that cleanup code to only run in the event of an exception?
One possible solution is this:
boolean ok = false;
try {
doWork();
ok = true;
} finally {
if (!ok) {
doCleanup();
}
}
It does exactly what I want, but I wondered if there was a more natural way to express the idea.
This alternative doesn’t pass muster:
try {
doWork();
} catch (Throwable e) {
doCleanup();
throw e; // BAD: Cant do this unless the enclosing function is declared to throw Throwable
}
I suppose I could catch Exception instead of Throwable, but I don't like the idea that a non-Exception throwable will bypass the cleanup code. After all, a regular finally
block still runs even for non-Exception throwables.
Aside: In C++, you would simply use a catch-all block:
try {
doWork();
} catch (...) {
doCleanup();
throw;
}
As of Java 7 this is legal code:
public static void method() {
try {
// stuff which doesn't declare checked exceptions
} catch (Throwable t) {
throw t;
}
}
The improved language rules allow this because static analysis can prove that t
will not actually be any checked exception.
Likewise, you are only required to declare the minimum necessary checked exceptions:
public static void method() throws IOException {
try {
throwingMethod();
} catch (Throwable t) { throw t; }
}
static void throwingMethod() throws IOException {}
If you have a try
...finally
block, then one of two cases applies:
throws
clause on the method, and the try
block may throw a checked exception.Have a catch
block that catches RuntimeException
s and any checked exceptions:
catch (RuntimeException | YourCheckedException e) {
// Cleanup
throw e;
}
throws
clause, and the try
block may only throw an unchecked exception.Catch RuntimeException
, which doesn't need to be declared in throws
.
catch (RuntimeException e) {
// Cleanup
throw e;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With