Excepciones encadenadas en Java

1. Información general

En este artículo, veremos brevemente qué es la excepción y profundizaremos en la discusión de las excepciones encadenadas en Java.

En pocas palabras, una excepción es un evento que perturba el flujo normal de ejecución del programa. Veamos ahora exactamente cómo podemos encadenar excepciones para sacarles una mejor semántica.

2. Excepciones encadenadas

La excepción encadenada ayuda a identificar una situación en la que una excepción provoca otra excepción en una aplicación.

Por ejemplo, considere un método que arroja una ArithmeticException debido a un intento de dividir por cero, pero la causa real de la excepción fue un error de E / S que causó que el divisor fuera cero. El método arrojará la ArithmeticException al llamador. La persona que llama no sabrá la causa real de una excepción . La excepción encadenada se utiliza en tales situaciones.

Este concepto se introdujo en JDK 1.4.

Veamos cómo se admiten las excepciones encadenadas en Java.

3. Clase de lanzar

La clase Throwable tiene algunos constructores y métodos para admitir excepciones encadenadas. En primer lugar, veamos los constructores.

  • Throwable (causa de Throwable) : Throwable tiene un solo parámetro, que especifica la causa real de una excepción .
  • Throwable (String desc, Throwable cause) : este constructor acepta unadescripción de Excepción con la causa real de una Excepción también.

A continuación, echemos un vistazo a los métodos que proporciona esta clase:

  • getCause () método - Este método devuelve la causa real asociado con la corriente de excepción .
  • initCause () método - Se establece una causa subyacente con la invocación de excepciones .

4. Ejemplo

Ahora, veamos el ejemplo en el que estableceremos nuestra propia descripción de excepción y lanzaremos una excepción encadenada :

public class MyChainedException { public void main(String[] args) { try { throw new ArithmeticException("Top Level Exception.") .initCause(new IOException("IO cause.")); } catch(ArithmeticException ae) { System.out.println("Caught : " + ae); System.out.println("Actual cause: "+ ae.getCause()); } } }

Como se adivinó, esto conducirá a:

Caught: java.lang.ArithmeticException: Top Level Exception. Actual cause: java.io.IOException: IO cause.

5. ¿Por qué las excepciones encadenadas?

Necesitamos encadenar las excepciones para que los registros sean legibles. Escribamos dos ejemplos. Primero sin encadenar las excepciones y segundo, con excepciones encadenadas. Más adelante, compararemos cómo se comportan los registros en ambos casos.

Para empezar, crearemos una serie de Excepciones:

class NoLeaveGrantedException extends Exception { public NoLeaveGrantedException(String message, Throwable cause) { super(message, cause); } public NoLeaveGrantedException(String message) { super(message); } } class TeamLeadUpsetException extends Exception { // Both Constructors }

Ahora, comencemos a usar las excepciones anteriores en ejemplos de código.

5.1. Sin encadenamiento

Escribamos un programa de ejemplo sin encadenar nuestras excepciones personalizadas.

public class MainClass { public void main(String[] args) throws Exception { getLeave(); } void getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { e.printStackTrace(); throw new NoLeaveGrantedException("Leave not sanctioned."); } } void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team Lead Upset"); } }

En el ejemplo anterior, los registros se verán así:

com.baeldung.chainedexception.exceptions.TeamLeadUpsetException: Team lead Upset at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:46) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Exception in thread "main" com.baeldung.chainedexception.exceptions. NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:37) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29)

5.2. Con encadenamiento

A continuación, escribamos un ejemplo con el encadenamiento de nuestras excepciones personalizadas:

public class MainClass { public void main(String[] args) throws Exception { getLeave(); } public getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { throw new NoLeaveGrantedException("Leave not sanctioned.", e); } } public void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team lead Upset."); } }

Finalmente, veamos los registros obtenidos con excepciones encadenadas:

Exception in thread "main" com.baeldung.chainedexception.exceptions .NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:36) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Caused by: com.baeldung.chainedexception.exceptions .TeamLeadUpsetException: Team lead Upset. at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:44) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) ... 1 more

Podemos comparar fácilmente los registros mostrados y concluir que las excepciones encadenadas conducen a registros más limpios.

En este artículo, echamos un vistazo al concepto de excepciones encadenadas.

La implementación de todos los ejemplos se puede encontrar en el proyecto Github; este es un proyecto basado en Maven, por lo que debería ser fácil de importar y ejecutar como está.