9 UncaughtExceptionHandler¶
UncaughtExceptionHandler¶
Como sabemos, en general en la JVM se pueden producir dos tipos de excepciones:
- Checked exceptions (excepciones comprobadas): Son aquellas que deben ser capturadas mediante
try-catch
o relanzadas incluyendo la cláusulathrows
en la declaración del método. Ejemplos de este tipo de excepciones sonIOException
oClassNotFoundException
. - Unchecked exceptions (excepciones no comprobadas): Son aquellas que NO es necesario capturar o relanzar, como por ejemplo
NumberFormatException
.
Cuando se genera una checked exception dentro del método run()
de un hilo (o de un objeto que implemente Runnable
), no tenemos más remedio que capturarla mediante try catch
, ya que NO podemos redefinir el método run()
añadiéndole la cláusula throws
.
Por su parte, si se produce una unchecked exception dentro del método run()
de un hilo, simplemente se mostrará el error en la consola y terminará la ejecución del programa.
Sin embargo, podemos modificar dicho comportamiento por defecto creando un objeto manejador (handler) que implemente la interfaz Thread.UncaughtExceptionHandler
, y asignándoselo al hilo mediante el método setUncaughtExceptionHandler(handler)
de la clase Thread
.
@FunctionalInterface
public interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
De esta manera, cuando se produzca una uncaught exception dentro del método run()
de dicho hilo, la JVM llamará al método uncaughtException()
del objeto manejador, pasándole el objeto Thead
y el objeto Exception
para que decida cómo manejar la situación, evitando así la finalización automática de ejecución de la aplicación.
La clase Thead
proporciona también el método estático Thread.setDefaultUncaughtExceptionHandler(handler)
que permite establecer el objeto manejador cuyo método uncaughtException()
debe ser llamado cuando se produzca una unchecked exception en cualquiera de los hilos del programa. De esta manera no será necesario indicar el manejador individualmente para cada hilo.
Así, en caso se producirse una unchecked exception dentro del método run()
de un hilo, la JVM sigue el siguiente procedimiento:
- Llamará al método
uncaughtException()
del objeto manejador establecido individualmente para dicho hilo. - Si no existe, llamará al método
uncaughtException()
del manejador establecido para el grupo de hilos al que pertenezca el hilo (ThreadGroup
, lo veremos más adelante). - Si no existe, llamará al del manejador por defecto establecido para la aplicación,
- Si ninguno de los anteriores existe, mostrará el error en la consola y finalizará la ejecución de la aplicación.
Proyecto UncaughtExceptionHandler¶
En este proyecto crearemos un programa que a conciencia produce una unchecked exception en un hilo, para que sea manejada por un objeto UncaughtExceptionHandler
que será asociado al mismo.
import java.lang.Thread.UncaughtExceptionHandler;
public class ExceptionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Thread: %s\n", t.getId());
System.out.printf("Exception: %s: %s\n", e.getClass().getName(), e.getMessage());
System.out.printf("Stack Trace: \n");
e.printStackTrace(System.out);
}
}
Si ejecutamos el programa veremos que se captura la excepción y se muestran datos sobre ella