2016-04-14 2 views
6

Ich benutze Java 8 Stream API, und wie wir wissen, unterstützt es nicht überprüft Ausnahmen in jeder funktionalen Schnittstelle in java.util.function.Ist es eine gute Lösung, die Checked Decorator-Funktion in der Stream-API zu verwenden?

Ich muss in der Regel Methode mit geprüften Ausnahmen innerhalb Ströme Operationen und ich habe geschrieben CheckedFunction Dekorateur innerhalb dieser Operationen zu verwenden:

import java.util.function.BiFunction; 
import java.util.function.Function; 

public interface CheckedFunction<T, R, E extends Throwable> { 

    R apply(T t) throws E; 

    static <T, R, CE extends Throwable, UCE extends RuntimeException> Function<T, R> checked(
      CheckedFunction<T, R, CE> checked, Function<CE, UCE> exceptionHandler) { 
     return (t) -> { 
      try { 
       return checked.apply(t); 
      } 
      catch (RuntimeException | Error e) { 
       throw e; 
      } 
      catch (Throwable e) { 
       // can't catch - compiler error 
       if (e instanceof InterruptedException) { 
        Thread.currentThread().interrupt(); 
       } 
       throw exceptionHandler.apply((CE) e); 
      } 
     }; 
    } 
} 

so kann ich es in solchen Fällen verwenden:

entities.stream() 
     .map(checked((entity) -> someResultChecked(entity), // throws IOException 
        (entity, e) -> { // e is of type IOException 
         log.error("exception during checked method of " + entity, e); 
         return new UncheckedIOException(e); 
        })) 
     .map(checked((entity) -> saveToDb(entity), // throws SQLException 
        (entity, e) -> { // e is of type SQLException 
         log.error("exception during saving " + entity, e); 
         return new UncheckedSQLException(e); 
        })) 
     .map(checked((entity) -> manyExceptionMethod(entity), // throws IOException, SQLException 
        (entity, e) -> { // e is of type Throwable 
         return new RuntimeException(e); 
        })) 

es wird jede geprüfte Ausnahme zu unkontrolliert wickeln, aber ich weiß, wenn Methode ist mehr als eine Ausnahme wirft es zu Throwable löschen wird, wie ich es in einfachen Fällen verwenden werde.

Ist es gute Idee, oder ich kann in versteckte Hindernisse laufen?

AKTUALISIERT: Wiederkehrende RuntimeExceptions.

Auch fand ich mehr klare Lösung in Jool mit der Handhabung InterruptedException die inkonsistentes Verhalten verursachen kann, wenn ignoriert: https://github.com/jOOQ/jOOL/blob/master/src/main/java/org/jooq/lambda/Unchecked.java

+1

Sie sollten einen Blick auf JavaRx nehmen, die für das Streaming mit Fehlerbehandlung – flakes

+0

Dank eine schöne API bietet, habe ich versucht, in mehrere Male zu sehen, aber immer gab up.Maybe es ist ein Signal, das ich brauche, um es zu klären, . – Monk3D

Antwort

0

Sie werden eine ClassCastException, wenn etwas anderes als ein IOException bekommt bekommen geworfen, da du bist alle Throwable fangen und sie in den UncheckedIOException Konstruktor übergeben, der nur einen IOException als Parameter nimmt. Da das Abfangen von IOException innerhalb eines funktionalen Typs ein so häufiges Bedürfnis ist, anstatt zu versuchen, zu verallgemeinern, sollte es am besten sein, es einfach zu halten und nur für diese geprüfte Ausnahme einen zu machen. Ich würde mir vorstellen, dass Sie Code nur selten duplizieren müssen, um das Gleiche für andere geprüfte Ausnahmen zu tun.

@FunctionalInterface 
public interface CheckedIOFunction<T,R> { 

    R apply(T t) throws IOException; 

    static <T, R> Function<T, R> toUnchecked(CheckedIOFunction<T, R> function) { 
     return t -> { 
      try { 
       return function.apply(t); 
      } catch (IOException ioe) { 
       throw new UncheckedIOException(ioe); 
      } 
     }; 
    } 
} 
+1

Nicht wirklich, leitet von der Methode, die ich verwende. Wenn ich also eine Methode verwenden will, die IOException auslöst, wird sein, und in ExceptionHandler wird e vom Typ IOException ausgegeben, und wenn es etwas anderes wirft, wird es vom Typ sein (oder vom Typ Throwable, wenn es sein wird mehrere Ausnahmen). Zum Beispiel können Sie Beispiel ausführen und Ausgabe sehen https://gist.github.com/gavlyukovskiy/30e28bae4b572b5a67c3a7c432069f46 – Monk3D

+0

Das ist eine interessante Idee. Gibt es endgültige Ausnahmetypen, die normalerweise ausgelöst werden? –

+0

Normalerweise verwenden wir nur eine einzige Ausnahme, so dass sie mit ihrem ungeprüften Analogon behandelt werden kann. Oder wir werfen UserApiException häufig auf, um auf Benutzeranforderungsprobleme hinzuweisen. – Monk3D

Verwandte Themen