The idiomatic Java finally block, which only works when thrown

If you have a cleanup code to run regardless of whether an exception has been thrown, try { ... } finally { ... }this is what you need. But what if you want this cleanup code to be executed only in case of an exception?

One possible solution is to:

boolean ok = false;
try {
    doWork();
    ok = true;
} finally {
    if (!ok) {
        doCleanup();
    }
}

He does exactly what I want, but I wondered if there was a more natural way to express the idea.

This alternative fails:

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 use Exception instead of Throwable, but I don't like the idea that a non-Exception throwable will bypass the cleanup code. After all, the regular block finallystill works even for non-exceptions.

Also: in C ++, you simply use the catch-all block:

try {
    doWork();
} catch (...) {
    doCleanup();
    throw;
}
+4
3

Java 7 :

public static void method() {
  try {
    // stuff which doesn't declare checked exceptions
  } catch (Throwable t) { 
    throw t; 
  }
}

, , t .

, :

public static void method() throws IOException {
  try {
    throwingMethod();
  } catch (Throwable t) { throw t; }
}

static void throwingMethod() throws IOException {}
+6

try... finally, :

  • throws , try .

catch, RuntimeException :

catch (RuntimeException | YourCheckedException e) {
    // Cleanup
    throw e;
}
  1. throws, try .

Catch RuntimeException, throws.

catch (RuntimeException e) {
    // Cleanup
    throw e;
}
+4

, , , .

, . Java , :

boolean ok = false;
try {
    doWork();
    ok = true;
} finally {
    if (!ok) {
        doCleanup();
    }
}

Java, ( ) .

, Java . . , ( , throwable.)

, IIRC, , . , , .

I would stick to the example you showed. It is clear what he is doing, he is clean, and there are no ashes and unexpected errors in him.

.ps.

For the love of God, I hope that you do not use C ++ catch-all idiom (at least not without its preceding battery lock type blocks, including std :: exception).

There is nothing worse than dealing with code that reaches such a catch-all block. There is no unnecessary information; it is almost impossible to trace what threw it.

I was there and did not do it for life. Nightmares.

+1
source

All Articles