Una excepción es un evento que ocurre durante la ejecución de un programa y detiene el flujo normal de la secuencia de instrucciones del programa.
El control de dichas excepciones se utiliza para la detección y corrección de errores. Si hay un error, la aplicación no debería "morirse".
Para manejar las excepciones en Java, se actúa de la siguiente manera:
- Se intenta (try) ejecutar la sentencia o bloque de sentencias que pueden producir algún error.
- Se captura (catch) las posibles excepciones que se hayan podido producir, ejecutando una serie de sentencias que informen o intenten resolver el error.
- Finalmente (finally) se puede ejecutar una serie de sentencias tanto si se ha producido un error como si todo ha ido bien.
Se debe utilizar el siguiente formato:
try {
//Sentencias que pueden producir error
} catch(ClaseExcepción variableRecogeExcepción) {
//Sentencias que informan o procuran solucionar el error.
//La variable variableRecogeExcepción no se tiene declarar antes.
} catch(ClaseExcepción2 variableRecogeExcepción2) {
//Puede haber varios catch. Uno para cada tipo de Exception.
} finally {
//Sentencias que deben ejecutarse en cualquier caso (opcional)
}
El elemento ClaseExcepción que aparece junto a catch, debe ser una de las clases de excepción. Al generarse el error durante la ejecución podemos comprobar qué clase de excepción se ha producido. De forma general, la clase Exceptionrecoge todos los tipos de excepciones. Si se desea un control más exhaustivo del tipo de error que se produce, se debe concretar más la clase de excepción correspondiente.
Por ejemplo, cuando se intenta convertir al tipo de dato numérico entero un dato introducido por el usuario en un campo de texto se utiliza una sentencia como:
int num = Integer.valueOf(campoNúmero.getText());
Si el valor introducido no es numérico, sino una cadena de caracteres, la llamada a Integer.valueOf produce una excepción, como se puede apreciar en la salida estándar:
Se puede apreciar que se produce una excepción del tipo NumberFormatException, por tanto se debería captura esa excepción para controlar el error.
try {
int num = Integer.valueOf(campoNúmero.getText());
} catch(NumberFormatException e) {
System.out.println("Error: El valor indicado no es un número");
}
En la documentación de la API puedes encontrar el tipo de excepción que lanza (throws) un determinado método. Para ello, observa si al final de la declaración del método aparece la sentencia throws. Por ejemplo, en el caso del método valueOf de la clase Integer se muestra:
Si no se tiene claro el tipo de excepción que se quiere controlar, o se quiere controlar cualquier tipo de excepción que se pueda producir, se puede indicar en el catch la clase Exception que es genérica para todas las excepciones, tal como se ha indicado anteriormente.
try {
int num = Integer.valueOf(campoNúmero.getText());
} catch(Exception e) {
System.out.println("Se ha detectado un error");
}
Obtener mensaje de la excepción
La variable que se indique en catch(), recoge información sobre la excepción que se ha producido. Es muy frecuente que a dicha variable se le asigne el nombre e ó ex. Si se desea mostrar qué tipo de error se ha producido se puede utilizar el método getMessage o el método toString (similar a getMessage pero además incluye el nombre de la clase de excepción) sobre la variable que se ha utilizado en el catch:
System.out.println(e.getMessage());
System.out.println(e.toString());
Al emplear una sentencia try, se deja de obtener el mensaje de error durante la ejecución que informaba entre otras cosas del número de línea donde se produjo la excepción. Ese mensaje suele ser interesante durante el desarrollo de la aplicación para realizar la depuración. Si se desea seguir obteniendo el mensaje de error junto con la pila de llamadas que se han producido puedes emplear el método printStackTrace.
e.printStackTrace();
Uso obligatorio de try-catch
En los ejemplos anteriores, se ha controlado la excepción que puede generar la llamada al método Integer.valueOf(), aunque dicho método no requiere obligatoriamente su uso. Se ha utilizado porque en un momento determinado se ha deseado controlar la introducción de texto en lugar de números.
Pero otros métodos requieren el uso de esta estructura try-catch obligatoriamente. Podrás comprobar que un método requiere su uso si se produce el siguiente error en la compilación o durante la edición en NetBeans:
error: unreported exception xxxxxxxxxxException; must be caught or declared to be thrown
Veamos algún ejemplo con la clase FileReader, la cual permite obtener el contenido de archivos alojados en el almacenamiento local del equipo. Uno de los métodos constructores de esta clase tiene la siguiente declaración, como puede verse en la API:
Si en el código fuente de una aplicación incluimos el siguiente trozo de código sin encerrarse en una estructura try-catch se producirá el error anterior.
Desde NetBeans, si haces clic en la bombilla del margen izquierda, podrás encerrar automáticamente esta sentencia dentro de un bloque try-catch usando la opción Surround Statement with try-catch:
De esa manera obtendrás el siguiente resultado:
Por defecto se usa la clase Logger para mostrar el mensaje correspondiente a la excepción que se produzca, pero puedes utilizar en su lugar cualquier otra sentencia.