método, pero sólo se ejecuta en la captura-ish AutoCloseable

arkadiusz:


Quisiera dos tienen dos métodos diferentes que se ejecutan en catchy finalbloques. He encontrado AutoCloseableinterfaz, pero necesito algo de fuego en caso de única excepción.
Me gusta:

SomeService service = CreateService().andOpenTransaction()

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

¿Hay alguna forma para que sea más sencillo? Como ya he dicho estoy familiarizado con AutoCloseable, pero me ayuda únicamente con bloque finally. Todavía no puedo usarlo dentro de la captura.

Lino:

Así se podría definir su propia interfaz, y algo staticmétodo corredor:

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

Que luego se podría llamar así:

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

Pero ya ves, que todavía está desordenado.

Incluso se puede poner en práctica este interfaceen tu SomeServicepero entonces usted está restringida que el run()método siempre llamará doSomeMessyThingsInsideDB().


Otra forma parecida, pero aún sería utilizar Java8 y crear un ayudante funcional interface:

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

Y luego una staticen algún método:

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 parte interesante es probablemente la siguiente: try(AutoCloseable ao = onFinally)que "registros" el onFinallymétodo que se llamará cuando finallyse alcanza.

Esto podría ser llamado como esto:

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

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=478544&siteId=1
Recomendado
Clasificación