Я хотел бы два из двух различных методов , работающих в catch
и final
блоки. Я нашел AutoCloseable
интерфейс, но мне нужно что - то огонь в случае единственным исключением.
Подобно:
SomeService service = CreateService().andOpenTransaction()
try {
service.doSomeMessyThingsInsideDB();
} catch (Exception e) {
service.rollbackTransaction();
throw e;
} finally {
service.closeConnection();
}
Есть ли способ сделать это проще? Как я сказал, что я знаком с AutoCloseable, но это помогает мне только, наконец, блок. Я до сих пор не могу использовать его в улове.
Ну вы можете определить свой собственный интерфейс, а затем некоторый static
метод бегун:
public interface ErrorHandlingCloseable extends AutoCloseable {
void run() throws Exception;
void onError(Exception e);
static void execute(ErrorHandlingClosable ehc) throws Exception {
try(ErrorHandlingClosable temp = ehc) {
ehc.run();
} catch(Exception e) {
ehc.onError(e);
throw e;
}
}
}
Что вы тогда могли бы назвать так:
SomeService service = CreateService().andOpenTransaction();
ErrorHandlingCloseable.execute(new ErrorHandlingCloseable() {
public void run() throws Exception { service.doSomeMessyThingsInsideDB(); }
public void onError(Exception e) { service.rollbackTransaction(); }
public void close() throws Exception { service.closeConnection(); }
});
Но вы видите, это все еще грязный.
Можно даже реализовать это interface
в ваших , SomeService
но тогда вы ограничены , что run()
метод всегда будет вызывать doSomeMessyThingsInsideDB()
.
Другой способ , но все - таки похоже было бы использовать Java8 и создать вспомогательный функционал interface
:
public interface ThrowingRunnable {
void run() throws Exception;
}
А затем static
метод где - то:
public static void execute(ThrowingRunnable action,
ThrowingRunnable onCatch,
ThrowingRunnable onFinally) throws Exception {
try(AutoCloseable ao = onFinally) {
action.run();
} catch(Exception e) {
onCatch.run();
throw e;
}
}
Самое интересное, наверное , это: try(AutoCloseable ao = onFinally)
, который «регистрирует» ваш onFinally
метод будет вызываться , когда finally
будет достигнута.
Это может тогда называться так:
execute(
service::doSomeMessyThingsInsideDB,
service::rollbackTransaction,
service::closeConnection
);