méthode AutoCloseable-ish, mais ne fonctionne que sur les prises

Arkadiusz:


Je voudrais deux ont deux méthodes différentes en cours d' exécution dans catchet finalblocs. J'ai trouvé l' AutoCloseableinterface, mais je dois quelque chose à feu en cas d'exception seulement.
Comme:

SomeService service = CreateService().andOpenTransaction()

try {
    service.doSomeMessyThingsInsideDB();
} catch (Exception e) {
    service.rollbackTransaction();
    throw e;
} finally {
    service.closeConnection();
}

Est-il possible de le rendre plus simple? Comme je l'ai dit que je suis familier avec AutoCloseable, mais il me permet seulement avec bloc finally. Je ne peux toujours pas l'utiliser à l'intérieur des prises.

Lino:

Eh bien , vous pouvez définir votre propre interface, puis une staticméthode de coureur:

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;
         }
     }
}

Alors que vous pourriez alors appeler comme ceci:

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(); }
});

Mais voyez-vous, il est salissant encore.

Vous pouvez même mettre en œuvre ce interfacedans votre SomeServicemais vous êtes limité que la run()méthode toujours faire appel doSomeMessyThingsInsideDB().


Une autre façon similaire , mais encore serait d'utiliser Java8 et créer une aide fonctionnelle interface:

public interface ThrowingRunnable {
   void run() throws Exception;
}

Et puis un staticendroit de la méthode:

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;
   }
}

La partie intéressante est sans doute celle - ci: try(AutoCloseable ao = onFinally)qui « registres » de votre onFinallyméthode à appeler quand finallyest atteint.

Cela pourrait alors être appelé comme ceci:

execute(
    service::doSomeMessyThingsInsideDB, 
    service::rollbackTransaction, 
    service::closeConnection
);

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=478542&siteId=1
conseillé
Classement