Gestion des exceptions à l'aide de Lambda dans Java 8
-
20-12-2019 - |
Question
Je fais quelques tests en utilisant des expressions lambda mais mon code ne se compile pas.Mon implémentation lambda est erronée ou la gestion des exceptions ?Quelle serait l’implémentation correcte du code suivant ?
class MyObject { }
interface Creatable<T> {
T create() throws IOException;
}
/* Using the code: */
Creatable<MyObject> creator = () -> {
try {
return new MyObject();
} catch (IOException e) {
e.printStackTrace();
}
};
MyObject obj1 = creator.create();
Si je supprime le bloc try catch et déclare l'exception à lancer dans la méthode, le code se compile et s'exécute normalement.
Creatable<MyObject> creator = () -> new MyObject();
L'erreur de compilation est :
incompatible types: bad return type in lambda expression
La solution
Votre lambda doit renvoyer un MyObject
.Si la try
le bloc se termine avec succès, c'est le cas, mais si ce n'est pas le cas, catch
le bloc est exécuté et ne renvoie rien.Vous pourriez donc écrire :
Creatable<MyObject> creator = () -> {
try {
return new MyObject();
} catch (IOException e) {
e.printStackTrace();
return null;
}
};
Mais vous obtiendrez alors une autre erreur de compilation :"IOException n'est jamais levée dans le bloc try".Vous auriez donc également besoin d'un constructeur MyObject
ça jette un IOException
:
class MyObject { MyObject() throws IOException {} }
En fin de compte, à moins que MyObject
lève en fait une exception, vous pouvez simplement utiliser :
Creatable<MyObject> creator = () -> new MyObject();
que l'on peut aussi écrire :
Creatable<MyObject> creator = MyObject::new;
Autres conseils
Lambda a besoin de tous les chemins pour renvoyer la valeur comme mentionné dans la réponse précédente. La solution simple consiste à revenir à la fin du bloc catch.
Cependant, il existe une manière plus élégante de gérer les exceptions lors de l'utilisation de lambda.
vous pouvez envelopper un lambda avec un autre exemple enveloppe ((x, y) -> x / y)))
Biconsumer<Integer,Integer> consumer wrap(Biconsumer<Integer,Integer> consumer)
{
return (v,k)->{try
{consumer.apply()}
catch(){};
}
https://www.youtube.com/watch?v=YLKMCPMLv60&list=PLqq-6Pq4lTTa9YGfyhyW2CqdtW9RtY-I3&index=18
@FunctionalInterface
public interface CreateThrowable<T, R, E extends Throwable> {
R create(T t) throws E;
static <T, R, E extends Throwable> Function<T, R> uncheckedException(ThrowingFunction<T, R, E> f) {
return t -> {
try {
return f.create(t);
} catch (Throwable e) {
throw new RuntimeException(e);
}
};
}
}