Directorio de artículos
Manejo de excepciones en java 8 lambda expresión
Introduccion
Las expresiones Lambda se introdujeron en Java 8. Las expresiones Lambda pueden hacer que nuestro código sea más breve y la lógica empresarial más clara, pero la interfaz funcional utilizada en las expresiones lambda no maneja muy bien las excepciones, porque estas interfaces funcionales proporcionadas por JDK Por lo general, no se produce ninguna excepción, lo que significa que debemos manejar manualmente la excepción nosotros mismos.
Debido a que las excepciones se dividen en Excepción no marcada y Excepción marcada, las discutimos por separado.
Manejar excepción no verificada
La excepción no verificada también se llama RuntimeException, que generalmente ocurre debido a un problema en nuestro código. RuntimeException no necesita ser capturado. En otras palabras, si hay una RuntimeException, se puede compilar sin atraparla.
Veamos un ejemplo:
List<Integer> integers = Arrays.asList(1,2,3,4,5);
integers.forEach(i -> System.out.println(1 / i));
Este ejemplo se puede compilar con éxito, pero hay un problema anterior, si hay un 0 en la lista, se generará una ArithmeticException.
Aunque esta es una excepción no verificada, aún queremos tratar con ella:
integers.forEach(i -> {
try {
System.out.println(1 / i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
});
En el ejemplo anterior, usamos try and catch para manejar la excepción, que es simple pero destruye la mejor práctica de la expresión lambda. El código se hincha.
Movemos el try y catch a un método wrapper:
static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
return i -> {
try {
consumer.accept(i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
};
}
Entonces la llamada original se convierte así:
integers.forEach(lambdaWrapper(i -> System.out.println(1 / i)));
Pero el contenedor sobre la captura ArithmeticException fija, lo adaptaremos a una clase más general:
static <T, E extends Exception> Consumer<T>
consumerWrapperWithExceptionClass(Consumer<T> consumer, Class<E> clazz) {
return i -> {
try {
consumer.accept(i);
} catch (Exception ex) {
try {
E exCast = clazz.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw ex;
}
}
};
}
La clase anterior pasa a una clase y la convierte en una excepción. Si se puede emitir, se procesa, de lo contrario se genera una excepción.
Después de este procesamiento, llamamos así:
integers.forEach(
consumerWrapperWithExceptionClass(
i -> System.out.println(1 / i),
ArithmeticException.class));
Manejar la excepción marcada
La excepción marcada es una excepción que debe manejarse, veamos un ejemplo:
static void throwIOException(Integer integer) throws IOException {
}
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
integers.forEach(i -> throwIOException(i));
Anteriormente definimos un método que arroja una IOException, que es una Excepción marcada y necesita ser manejada, por lo que en lo siguiente para Cada, el programa no se compilará porque la excepción correspondiente no se maneja.
La forma más fácil es intentar atrapar, como se muestra a continuación:
integers.forEach(i -> {
try {
throwIOException(i);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Por supuesto, las desventajas de este enfoque ya se han mencionado anteriormente. De manera similar, podemos definir un nuevo método de envoltura:
static <T> Consumer<T> consumerWrapper(
ThrowingConsumer<T, Exception> throwingConsumer) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
Llamamos así:
integers.forEach(consumerWrapper(i -> throwIOException(i)));
También podemos encapsular la excepción:
static <T, E extends Exception> Consumer<T> consumerWrapperWithExceptionClass(
ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
try {
E exCast = exceptionClass.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw new RuntimeException(ex);
}
}
};
}
Entonces llámalo así:
integers.forEach(consumerWrapperWithExceptionClass(
i -> throwIOException(i), IOException.class));
Resumen
Este artículo describe cómo manejar las excepciones marcadas y no marcadas en las expresiones lambda, espero brindarle ayuda.
Ejemplo de este artículo https://github.com/ddean2009/learn-java-streams/tree/master/lambda-exception
Bienvenido a prestar atención a mi número público: esas cosas del programa, ¡más emocionante esperando por ti!
Para obtener más información, visite www.flydean.com.