AutoCloseable-ish Methode aber läuft nur auf Fang

Arkadiusz:


Ich möchte zwei zwei verschiedene Methoden laufen in catchund finalBlöcke. Ich habe festgestellt AutoCloseableSchnittstelle, aber ich brauche nur etwas Feuer bei Ausnahme.
Mögen:

SomeService service = CreateService().andOpenTransaction()

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

Gibt es eine Möglichkeit, es einfacher zu machen? Wie ich sagte, ich bin vertraut mit AutoCloseable, aber es hilft mir nur mit finally-Block. Ich kann es immer noch nicht in dem Fang verwenden.

Lino:

Nun könnten Sie Ihre eigene Schnittstelle definieren, und dann einige staticLäufer - Methode:

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

Was Sie dann dann so nennen könnte:

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

Aber sehen Sie, es ist immer noch chaotisch.

Man könnte sogar diese implementieren interfacein Ihrem SomeServiceaber dann sind Sie beschränkt , dass die run()Methode immer nennen doSomeMessyThingsInsideDB().


Ein anderer Weg , aber immer noch ähnlich wäre Java8 zu verwenden , und erstellen Sie einen Helfer funktional interface:

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

Und dann eine staticMethode irgendwo:

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

Der interessante Teil ist dies wahrscheinlich: try(AutoCloseable ao = onFinally), die „Register“ Ihre onFinallyMethode aufgerufen werden , wenn finallyerreicht wird.

Dies könnte dann wie folgt aufgerufen werden:

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

Ich denke du magst

Origin http://10.200.1.11:23101/article/api/json?id=478537&siteId=1
Empfohlen
Rangfolge