AutoCloseable-иш метод, но работает только на улове

Arkadiusz:


Я хотел бы два из двух различных методов , работающих в 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
);

рекомендация

отhttp://10.200.1.11:23101/article/api/json?id=478538&siteId=1