web-dev-qa-db-fra.com

Fonction Java 8 Lambda qui lève une exception?

Je sais comment créer une référence à une méthode qui a un paramètre String et retourne une int, c'est:

Function<String, Integer>

Cependant, cela ne fonctionne pas si la fonction lève une exception, par exemple, elle est définie comme suit:

Integer myMethod(String s) throws IOException

Comment définirais-je cette référence?

384
Triton Man

Vous devrez faire l'une des choses suivantes.

  • Si c'est votre code, alors définissez votre propre interface fonctionnelle qui déclare l'exception vérifiée

    @FunctionalInterface
    public interface CheckedFunction<T, R> {
       R apply(T t) throws IOException;
    }
    

    et l'utiliser

    void foo (CheckedFunction f) { ... }
    
  • Sinon, encapsulez Integer myMethod(String s) dans une méthode qui ne déclare pas une exception vérifiée:

    public Integer myWrappedMethod(String s) {
        try {
            return myMethod(s);
        }
        catch(IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    

    et alors

    Function<String, Integer> f = (String t) -> myWrappedMethod(t);
    

    ou

    Function<String, Integer> f =
        (String t) -> {
            try {
               return myMethod(t);
            }
            catch(IOException e) {
                throw new UncheckedIOException(e);
            }
        };
    
338
jason

Vous pouvez réellement étendre Consumer (et Function etc.) avec une nouvelle interface qui gère les exceptions - en utilisant les méthodes default de Java 8!

Considérez cette interface (étend Consumer):

@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {

    @Override
    default void accept(final T elem) {
        try {
            acceptThrows(elem);
        } catch (final Exception e) {
            // Implement your own exception handling logic here..
            // For example:
            System.out.println("handling an exception...");
            // Or ...
            throw new RuntimeException(e);
        }
    }

    void acceptThrows(T elem) throws Exception;

}

Ensuite, par exemple, si vous avez une liste:

final List<String> list = Arrays.asList("A", "B", "C");

Si vous voulez le consommer (par exemple avec forEach) avec du code qui lève des exceptions, vous auriez traditionnellement mis en place un bloc try/catch:

final Consumer<String> consumer = aps -> {
    try {
        // maybe some other code here...
        throw new Exception("asdas");
    } catch (final Exception ex) {
        System.out.println("handling an exception...");
    }
};
list.forEach(consumer);

Mais avec cette nouvelle interface, vous pouvez l'instancier avec une expression lambda et le compilateur ne se plaindra pas:

final ThrowingConsumer<String> throwingConsumer = aps -> {
    // maybe some other code here...
    throw new Exception("asdas");
};
list.forEach(throwingConsumer);

Ou même simplement le lancer pour être plus succinct!:

list.forEach((ThrowingConsumer<String>) aps -> {
    // maybe some other code here...
    throw new Exception("asda");
});

Update: Il semble y avoir une très jolie bibliothèque d’utilitaires dans Durian appelée Errors qui peut être utilisée pour résoudre ce problème avec beaucoup plus de souplesse. Par exemple, dans mon implémentation ci-dessus, j'ai explicitement défini la stratégie de traitement des erreurs (System.out... ou throw RuntimeException), alors que les erreurs de Durian vous permettent d'appliquer une stratégie à la volée via une vaste suite de méthodes utilitaires. Merci pour le partage , @NedTwigg !.

Exemple d'utilisation:

list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
170
jlb

Je pense que la classe Errors de Durian combine plusieurs des avantages des diverses suggestions ci-dessus.

Pour inclure Durian dans votre projet, vous pouvez soit:

55
Ned Twigg

Ceci n’est pas spécifique à Java 8. Vous essayez de compiler quelque chose d’équivalent à:

interface I {
    void m();
}
class C implements I {
    public void m() throws Exception {} //can't compile
}
25
assylias

Avertissement: je n'ai pas encore utilisé Java 8, seulement lu à ce sujet.

Function<String, Integer> ne lance pas IOException, vous ne pouvez donc y insérer aucun code aussi throws IOException. Si vous appelez une méthode qui attend un Function<String, Integer>, le lambda que vous lui transmettez ne peut pas lancer IOException, point. Vous pouvez soit écrire un lambda comme ceci (je pense que c'est la syntaxe lambda, pas sûr):

(String s) -> {
    try {
        return myMethod(s);
    } catch (IOException ex) {
        throw new RuntimeException(ex);
        // (Or do something else with it...)
    }
}

Ou, si la méthode à laquelle vous transmettez le lambda est celle que vous avez écrite vous-même, vous pouvez définir une nouvelle interface fonctionnelle et l'utiliser comme type de paramètre au lieu de Function<String, Integer>:

public interface FunctionThatThrowsIOException<I, O> {
    O apply(I input) throws IOException;
}
11
Adam R. Nelson

Si cela ne vous dérange pas d'utiliser une librairie tierce ( Vavr ), vous pouvez écrire

CheckedFunction1<String, Integer> f = this::myMethod;

Il possède également la prétendue monade Try qui gère les erreurs:

Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
        .map(i -> ...) // only executed on Success
        ...

S'il vous plaît lire plus ici .

Disclaimer: Je suis le créateur de Vavr.

7
Daniel Dietrich

Vous pouvez utiliser unthrow wrapper

Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));

ou

Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
6
SeregaLBN

Vous pouvez.

Etendre la UtilException de @marcg et ajouter le <E extends Exception> générique si nécessaire: le compilateur vous obligera de nouveau à ajouter des clauses throw et tout se passe comme si vous pouviez lancer des exceptions vérifiées de manière native sur les flux Java 8.

public final class LambdaExceptionUtil {

    @FunctionalInterface
    public interface Function_WithExceptions<T, R, E extends Exception> {
        R apply(T t) throws E;
    }

    /**
     * .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
     */
    public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E  {
        return t -> {
            try {
                return function.apply(t);
            } catch (Exception exception) {
                throwActualException(exception);
                return null;
            }
        };
    }

    @SuppressWarnings("unchecked")
    private static <E extends Exception> void throwActualException(Exception exception) throws E {
        throw (E) exception;
    }

}

public class LambdaExceptionUtilTest {

    @Test
    public void testFunction() throws MyTestException {
        List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
        assertEquals(2, sizes.size());
        assertEquals(4, sizes.get(0).intValue());
        assertEquals(5, sizes.get(1).intValue());
    }

    private Integer transform(String value) throws MyTestException {
        if(value==null) {
            throw new MyTestException();
        }
        return value.length();
    }

    private static class MyTestException extends Exception { }
}
5
PaoloC

Ce problème me préoccupe également; c'est pourquoi j'ai créé ce projet .

Avec cela, vous pouvez faire:

final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;

Il existe un total de 39 interfaces définies par le JDK qui ont un tel équivalent Throwing; Ce sont tous des @FunctionalInterfaces utilisés dans les flux (Stream de base, mais aussi IntStream, LongStream et DoubleStream).

Et comme chacun d'eux étend sa contrepartie non lanceuse, vous pouvez également les utiliser directement dans lambdas:

myStringStream.map(f) // <-- works

Le comportement par défaut est que lorsque votre jeté lambda lève une exception vérifiée, une ThrownByLambdaException est levée avec l'exception vérifiée comme cause. Vous pouvez donc capturer cela et en connaître la cause.

D'autres fonctionnalités sont également disponibles.

4
fge

Vous pouvez cependant créer votre propre FunctionalInterface qui se présente comme ci-dessous.

@FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
  void accept(T instance) throws X;
}

puis implémentez-le en utilisant Lambdas ou des références comme indiqué ci-dessous.

import Java.io.FileWriter;
import Java.io.IOException;

//lambda expressions and the execute around method (EAM) pattern to
//manage resources

public class FileWriterEAM  {
  private final FileWriter writer;

  private FileWriterEAM(final String fileName) throws IOException {
    writer = new FileWriter(fileName);
  }
  private void close() throws IOException {
    System.out.println("close called automatically...");
    writer.close();
  }
  public void writeStuff(final String message) throws IOException {
    writer.write(message);
  }
  //...

  public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {

    final FileWriterEAM writerEAM = new FileWriterEAM(fileName);    
    try {
      block.accept(writerEAM);
    } finally {
      writerEAM.close();
    }
  }

  public static void main(final String[] args) throws IOException {

    FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));

    FileWriterEAM.use("eam2.txt", writerEAM -> {
        writerEAM.writeStuff("how");
        writerEAM.writeStuff("sweet");      
      });

    FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);     

  }


 void writeIt() throws IOException{
     this.writeStuff("How ");
     this.writeStuff("sweet ");
     this.writeStuff("it is");

 }

}
4
JohnnyO

Idiotisme de lancer sournois permet de contourner CheckedException de l'expression Lambda. Le fait d'insérer une CheckedException dans une RuntimeException n'est pas bon pour la gestion d'erreur stricte.

Il peut être utilisé comme une fonction Consumer utilisée dans une collection Java.

Voici une version simple et améliorée de la réponse de jib .

import static Throwing.rethrow;

@Test
public void testRethrow() {
    thrown.expect(IOException.class);
    thrown.expectMessage("i=3");

    Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
        int i = e.intValue();
        if (i == 3) {
            throw new IOException("i=" + i);
        }
    }));
}

Cela enveloppe le lambda dans un rethrow. CheckedException rediffuse toute Exception qui a été jetée dans votre lambda.

public final class Throwing {
    private Throwing() {}

    @Nonnull
    public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
        return consumer;
    }

    /**
     * The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
     * allows the unchecked exception to propagate.
     * 
     * http://www.baeldung.com/Java-sneaky-throws
     */
    @SuppressWarnings("unchecked")
    @Nonnull
    public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
        throw (E) ex;
    }

}

Trouvez un code complet et des tests unitaires ici .

4
myui

J'ai eu ce problème avec Class.forName et Class.newInstance dans un lambda, alors je viens de le faire:

public Object uncheckedNewInstanceForName (String name) {

    try {
        return Class.forName(name).newInstance();
    }
    catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

À l'intérieur du lambda, au lieu d'appeler Class.forName ("myClass"). NewInstance () Je viens d'appeler uncheckedNewInstanceForName ("myClass")

4
Sergio

Il y a beaucoup d'excellentes réponses déjà publiées ici. Juste essayer de résoudre le problème avec une perspective différente. C'est juste mes 2 cents, corrigez-moi s'il vous plaît si je me trompe quelque part. 

La clause Throws dans FunctionalInterface n'est pas une bonne idée

Je pense que ce n'est probablement pas une bonne idée d'appliquer des exceptions IOException pour les raisons suivantes

  • Cela me semble un anti-motif pour Stream/Lambda. L'idée est que l'appelant décide du code à fournir et de la gestion de l'exception. Dans de nombreux scénarios, l'exception IOException peut ne pas être applicable pour le client. Par exemple, si le client obtient une valeur de la mémoire cache/mémoire au lieu d'effectuer des E/S réelles. 

  • En outre, la gestion des exceptions dans les flux devient vraiment hideuse. Par exemple, voici mon code ressemblera si j'utilise votre API

               acceptMyMethod(s -> {
                    try {
                        Integer i = doSomeOperation(s);
                        return i;
                    } catch (IOException e) {
                        // try catch block because of throws clause
                        // in functional method, even though doSomeOperation
                        // might not be throwing any exception at all.
                        e.printStackTrace();
                    }
                    return null;
                });
    

    Moche n'est-ce pas? De plus, comme je l’ai mentionné dans mon premier point, la méthode doSomeOperation peut ou non renvoyer une exception IOException (selon l’implémentation du client/appelant), mais en raison de la clause throws de votre méthode FunctionalInterface, je dois toujours écrire le essayer-attraper.

Que dois-je faire si je sais vraiment que cette API génère une exception IOException

  • Nous confondons donc probablement FunctionalInterface avec des interfaces typiques. Si vous savez que cette API lève une exception IOException, il est fort probable que vous connaissiez également un comportement par défaut/abstrait. Je pense que vous devriez définir une interface et déployer votre bibliothèque (avec une implémentation par défaut/abstraite) comme suit

    public interface MyAmazingAPI {
        Integer myMethod(String s) throws IOException;
    }
    

    Cependant, le problème du try-catch existe toujours pour le client. Si j'utilise votre API dans le flux, j'ai toujours besoin de gérer l'IOException dans un bloc try-catch hideux.

  • Fournissez une API par défaut conviviale pour les flux, comme suit

    public interface MyAmazingAPI {
        Integer myMethod(String s) throws IOException;
    
        default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) {
            try {
                return Optional.ofNullable(this.myMethod(s));
            } catch (Exception e) {
                if (exceptionConsumer != null) {
                    exceptionConsumer.accept(e);
                } else {
                    e.printStackTrace();
                }
            }
    
            return Optional.empty();
        }
    }
    

    La méthode par défaut prend l'objet consommateur en argument, qui sera responsable de gérer l'exception. Du point de vue du client, le code ressemblera à ceci:

    strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
                    .filter(Optional::isPresent)
                    .map(Optional::get).collect(toList());
    

    Bonne droite? Bien sûr, un enregistreur ou une autre logique de traitement pourrait être utilisé à la place de Exception :: printStackTrace. 

  • Vous pouvez également exposer une méthode similaire à https://docs.Oracle.com/javase/8/docs/api/Java/util/concurrent/CompletableFuture.html#exceptionally-Java.util.function.Function- . Ce qui signifie que vous pouvez exposer une autre méthode, qui contiendra l'exception de l'appel de la méthode précédente. L'inconvénient est que vous rendez maintenant vos API dynamiques, ce qui signifie que vous devez gérer la sécurité des threads et que ces performances finiront par devenir un succès. Juste une option à considérer si. 

3
TriCore

Une autre solution utilisant un wrapper Function serait de renvoyer une instance d'un wrapper de votre résultat, par exemple Success, si tout se passe bien, soit une instance de, par exemple Failure.

Quelques codes pour clarifier les choses:

public interface ThrowableFunction<A, B> {
    B apply(A a) throws Exception;
}

public abstract class Try<A> {

    public static boolean isSuccess(Try tryy) {
        return tryy instanceof Success;
    }

    public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
        return a -> {
            try {
                B result = function.apply(a);
                return new Success<B>(result);
            } catch (Exception e) {
                return new Failure<>(e);
            }
        };
    }

    public abstract boolean isSuccess();

    public boolean isError() {
        return !isSuccess();
    }

    public abstract A getResult();

    public abstract Exception getError();
}

public class Success<A> extends Try<A> {

    private final A result;

    public Success(A result) {
        this.result = result;
    }

    @Override
    public boolean isSuccess() {
        return true;
    }

    @Override
    public A getResult() {
        return result;
    }

    @Override
    public Exception getError() {
        return new UnsupportedOperationException();
    }

    @Override
    public boolean equals(Object that) {
        if(!(that instanceof Success)) {
            return false;
        }
        return Objects.equal(result, ((Success) that).getResult());
    }
}

public class Failure<A> extends Try<A> {

    private final Exception exception;

    public Failure(Exception exception) {
        this.exception = exception;
    }

    @Override
    public boolean isSuccess() {
        return false;
    }

    @Override
    public A getResult() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Exception getError() {
        return exception;
    }
}

Un cas d'utilisation simple:

List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
    map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
    collect(Collectors.toList());
3
yohan

Vous pouvez utiliser ET pour cela. ET est une petite bibliothèque Java 8 pour la conversion/traduction des exceptions.

Avec ET cela ressemble à ceci:

// Do this once
ExceptionTranslator et = ET.newConfiguration().done();

...

// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));

// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));

Les instances ExceptionTranslator sont thread-safe et peuvent être partagées par plusieurs composants. Vous pouvez configurer des règles de conversion d'exception plus spécifiques (par exemple, FooCheckedException -> BarRuntimeException) si vous le souhaitez. Si aucune autre règle n'est disponible, les exceptions cochées sont automatiquement converties en RuntimeException.

(Avertissement: je suis l'auteur d'ET)

3
micha

Par défaut, Java 8 Function ne permet pas de lever une exception et, comme le suggèrent plusieurs réponses, il existe de nombreuses façons de l'obtenir.

@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
    R apply(T t) throws E;
}

Définir en tant que:

private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
    if ("abc".equals(str)) {
        throw new IOException();
    }
  return 1;
};

Et ajoutez throws ou try/catch la même exception dans la méthode de l'appelant.

2
Arpit

Créez un type de retour personnalisé qui propagera l'exception vérifiée. C'est une alternative à la création d'une nouvelle interface qui reflète l'interface fonctionnelle existante avec la légère modification d'une "exception de projection" sur la méthode de l'interface fonctionnelle.

Définition

CheckedValueSupplier

public static interface CheckedValueSupplier<V> {
    public V get () throws Exception;
}

CheckedValue

public class CheckedValue<V> {
    private final V v;
    private final Optional<Exception> opt;

    public Value (V v) {
        this.v = v;
    }

    public Value (Exception e) {
        this.opt = Optional.of(e);
    }

    public V get () throws Exception {
        if (opt.isPresent()) {
            throw opt.get();
        }
        return v;
    }

    public Optional<Exception> getException () {
        return opt;
    }

    public static <T> CheckedValue<T> returns (T t) {
        return new CheckedValue<T>(t);
    }

    public static <T> CheckedValue<T> rethrows (Exception e) {
        return new CheckedValue<T>(e);
    }

    public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
        try {
            return CheckedValue.returns(sup.get());
        } catch (Exception e) {
            return Result.rethrows(e);
        }
    }

    public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
        try {
            return CheckedValue.returns(sup.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Usage

//  Don't use this pattern with FileReader, it's meant to be an
//  example.  FileReader is a Closeable resource and as such should
//  be managed in a try-with-resources block or in another safe
//  manner that will make sure it is closed properly.

//  This will not compile as the FileReader constructor throws
//  an IOException.
    Function<String, FileReader> sToFr =
        (fn) -> new FileReader(Paths.get(fn).toFile());

// Alternative, this will compile.
    Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
        return CheckedValue.from (
            () -> new FileReader(Paths.get("/home/" + f).toFile()));
    };

// Single record usage
    // The call to get() will propagate the checked exception if it exists.
    FileReader readMe = pToFr.apply("/home/README").get();


// List of records usage
    List<String> paths = ...; //a list of paths to files
    Collection<CheckedValue<FileReader>> frs =
        paths.stream().map(pToFr).collect(Collectors.toList());

// Find out if creation of a file reader failed.
    boolean anyErrors = frs.stream()
        .filter(f -> f.getException().isPresent())
        .findAny().isPresent();

Que se passe-t-il?

Ajouter "exception d'exception" à chaque interface fonctionnelle du kit JDK violerait le principe DRY de la manière la plus odieuse. Afin d'éviter cela, une interface fonctionnelle unique générant une exception vérifiée est créée (CheckedValueSupplier). Ce sera la seule interface fonctionnelle qui autorise les exceptions vérifiées. Toutes les autres interfaces fonctionnelles utiliseront la CheckedValueSupplier pour envelopper tout code qui lève une exception vérifiée.

La classe CheckedValue conservera le résultat de l'exécution de toute logique qui lève une exception vérifiée. Cela empêche la propagation d'une exception vérifiée jusqu'au moment où le code tente d'accéder à la valeur contenue dans une instance de CheckedValue.

Les problèmes avec cette approche.

  • Nous lançons maintenant "Exception" en masquant efficacement le type spécifique initialement lancé.
  • Nous ignorons qu'une exception s'est produite jusqu'à ce que CheckedValue#get() soit appelé.

Consommateur et al

Certaines interfaces fonctionnelles (Consumer par exemple) doivent être gérées différemment car elles ne fournissent pas de valeur de retour.

Fonction tenant lieu de consommateur

Une approche consiste à utiliser une fonction au lieu d'un consommateur, qui s'applique lors de la gestion des flux.

    List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
    .map(e -> CheckedValueSupplier.from(
        () -> {throwyMethod(e); return e;}))
    .filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior

Intensifier

Sinon, vous pouvez toujours passer à RuntimeException. Il existe d'autres réponses qui couvrent l'escalade d'une exception vérifiée à partir d'une Consumer.

Ne consomme pas.

Il suffit d’éviter les interfaces fonctionnelles dans leur ensemble et d’utiliser une boucle de qualité supérieure.

2
justin.hughey

Si cela ne vous dérange pas d'utiliser une bibliothèque tierce, avec cyclops-react , une bibliothèque à laquelle je contribue, vous pouvez utiliser l'API FluentFunctions pour écrire

 Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);

ofChecked prend jOOλ CheckedFunction et renvoie la référence assouplie à une fonction JDK Java.util.function.Function standard (non cochée).

Sinon, vous pouvez continuer à utiliser la fonction capturée via l'API FluentFunctions!

Par exemple, pour exécuter votre méthode, réessayez-la 5 fois et enregistrez son statut, vous pouvez écrire 

  FluentFunctions.ofChecked(this::myMethod)
                 .log(s->log.debug(s),e->log.error(e,e.getMessage())
                 .try(5,1000)
                 .apply("my param");
1
John McClean

Ce que je fais est de permettre à l'utilisateur de donner la valeur qu'il souhaite réellement en cas d'exception ..__ 

public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
    return x -> {
        try {
            return delegate.apply(x);
        } catch (Throwable throwable) {
            return defaultValue;
        }
    };
}

@FunctionalInterface
public interface FunctionThatThrows<T, R> {
    R apply(T t) throws Throwable;
}

Et cela peut alors être appelé comme: 

defaultIfThrows(child -> child.getID(), null)
1
mmounirou

Utilisez Jool Library ou dites jOOλ library à partir de JOOQ. Il fournit non seulement des interfaces gérées par des exceptions non vérifiées mais fournit également à la classe Seq de nombreuses méthodes utiles. 

En outre, il contient des interfaces fonctionnelles avec jusqu'à 16 paramètres. En outre, il fournit la classe Tuple qui est utilisée dans différents scénarios.

Jool Git Link

Spécifiquement dans la recherche de bibliothèque pour le package org.jooq.lambda.fi.util.function. Il contient toutes les interfaces de Java-8 avec Checked ajouté. Voir ci-dessous pour référence: -

 enter image description here

0
Vinay Prajapati

Je suis l'auteur d'une petite bibliothèque avec une magie générique pour lancer n'importe quelle exception Java n'importe où sans avoir besoin de les capturer ni de les envelopper dans RuntimeException.

Utilisation: unchecked(() -> methodThrowingCheckedException())

public class UncheckedExceptions {

    /**
     * throws {@code exception} as unchecked exception, without wrapping exception.
     *
     * @return will never return anything, return type is set to {@code exception} only to be able to write <code>throw unchecked(exception)</code>
     * @throws T {@code exception} as unchecked exception
     */
    @SuppressWarnings("unchecked")
    public static <T extends Throwable> T unchecked(Exception exception) throws T {
        throw (T) exception;
    }


    @FunctionalInterface
    public interface UncheckedFunction<R> {
        R call() throws Exception;
    }

    /**
     * Executes given function,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @return result of function
     * @see #unchecked(Exception)
     */
    public static <R> R unchecked(UncheckedFunction<R> function) {
        try {
            return function.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }


    @FunctionalInterface
    public interface UncheckedMethod {
        void call() throws Exception;
    }

    /**
     * Executes given method,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @see #unchecked(Exception)
     */
    public static void unchecked(UncheckedMethod method) {
        try {
            method.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }
}

source: https://github.com/qoomon/unchecked-exceptions-Java

0
qoomon

Je vais faire quelque chose de générique:

public interface Lambda {

    @FunctionalInterface
    public interface CheckedFunction<T> {

        T get() throws Exception;
    }

    public static <T> T handle(CheckedFunction<T> supplier) {
        try {
            return supplier.get();
        } catch (Exception exception) {
            throw new RuntimeException(exception);

        }
    }
}

usage:

 Lambda.handle(() -> method());
0
ahll

Plusieurs des solutions proposées utilisent un argument générique de E pour transmettre le type de l'exception qui est levée.

Allez plus loin, et plutôt que de passer du type d'exception à un consommateur du type d'exception, comme dans ...

Consumer<E extends Exception>

Vous pouvez créer plusieurs variantes réutilisables de Consumer<Exception> qui couvriraient les besoins courants de gestion des exceptions de votre application. 

0
Rodney P. Barbati