En PC Resumen hablaremos de las formas en que se puede utilizar las sentencias try y catch en Java. A pesar de que el gestor de excepciones que proporciona Java es útil para la depuración, generalmente el programador prefiere manejar la excepción él mismo. Esto aporta dos ventajas. En primer lugar, permite corregir el error. En segundo lugar, evita que el programa concluya de forma automática.
Para evitar esta situación y gestionar el error en tiempo de ejecución, sencillamente se debe incluir el código que queramos controlar dentro de un bloque try. Inmediatamente después del bloque try, se incluye la cláusula catch que especifica el tipo de excepción que se desea capturar.
Veamos ahora un ejemplo sencillo para capturar la excepción ArithmeticException generada por la división por cero.
class Exc2 {
public static void main (String args[]) {
int d, a;
try { // Controla un bloque de código.
d = 0;
a = 42 / d;
System.out.println("Esto no se imprimirá.");
} Catch (ArithmeticException e) { // Captura el error
System.out.println("División por cero !!");
}
System.out.println("Después del catch");
}
}
Este programa generaría la siguiente salida:
División por cero !!
Después del catch
Tenga en cuenta que la llamada a println dentro del try no llegará a ejecutarse. Una vez generada una excepción, el control del programa pasa al bloque catch. Una vez finalizado este bloque, el programa continúa.
Un bloque try y su correspondiente catch forman una unidad. El campo de acción de una cláusula catch se limita a aquellas sentencias especificadas por la sentencia try que la precede inmediatamente. Las sentencias protegidas por try deben estar entre llaves, es decir deben estar en un bloque.
El objetivo de la mayoría de cláusulas catch bien construidas debe ser el de resolver la condición excepcional y luego continuar como si no hubiera pasado nada.
La clase Throwable son descendientes todas las excepciones, sobreescriben el método toString, definido por Object y devuelve una cadena que contiene la descripción de la excepción. La descripción la podemos imprimir, pasando simplemente la excepción como parámetro.
Por ejemplo:
catch (ArithmeticException e) {
System.out.println("Excepción:" + e);
}
Este código en el caso del programa anterior sacaría por pantalla:
Excepción: java.lang.ArithmeticException: /by zero
Aunque en este caso el mensaje no tiene mucho interés, la posibilidad de presentar la descripción de la excepción es de un gran valor, sobre todo cuando se está experimentando con las excepciones o se está depurando un programa.
Cláusulas catch múltiples
En ciertos casos, una única secuencia de código, puede originar más de un tipo de excepción. Para controlar estas situaciones, pueden especificarse más de una cláusula catch, para que cada una de ellas capture un tipo diferente de excepción. Cuando se lanza una excepción, se inspecciona cada sentencia catch, y se ejecuta la primera que coincida con la excepción. Una vez ejecutada esta es continúa después del bloque try / catch.
Por ejemplo:
class MultiCatch {
public static void main (String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = {1};
c[42] = 99;
} Catch (ArithmeticException e) {
System.out.println("División por 0: " + e);
} Catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Te has salido del array " + e);
}
System.out.println("Después de los bloques try / catch");
}
}
Desde el JDK 1.8, también se puede estructurar de la siguiente manera la cláusula catch cuando es necesario controlar varias excepciones:
class MultiCatch {
public static void main (String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = {1};
c[42] = 99;
} Catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
System.out.println("Después de los bloques try / catch");
}
}
Este programa provocará una excepción de división por cero si se ejecuta sin parámetros en la línea de comandos. Pero sino aparecerá una excepción de tipo ArrayIndexOutOfBoundsException ya que intentamos acceder a la posición 42 de una mesa de tamaño 1.
Si utilizamos varias sentencias catch, hay que tener claro que las subclases de excepción deben ir ante cualquiera de sus superclases. Esto es así porque la sentencia catch que utiliza una superclase, capturará excepciones de este tipo más cualquiera de sus subclases y por lo tanto éstas no se ejecutarán si están tras la superclase. Además, en Java se produce error si hay un código inalcanzable.
Sentencias try anidadas
Las sentencias try pueden estar dentro del bloque de otra sentencia try. Cada vez que se introduce una sentencia try el contexto de esta excepción también se almacena en la pila. Si una sentencia try no tiene su correspondiente gestor catch para una excepción determinada, se examina la pila buscando los gestores catch de las siguientes sentencias try para localizar una coincidencia. Este proceso continúa hasta que se encuentra la coincidencia catch adecuada o hasta que se acaban las sentencias try. Si no se encuentra ninguna, el intérprete Java gestionará la excepción.
Las sentencias try anidadas pueden darse también de una forma menos obvia cuando se implican las llamadas a métodos. Por ejemplo, se puede incluir una llamada a un método dentro de un bloque try, y si dentro de este método hay otra sentencia try, esta se encuentra nidada dentro del bloque try externo que llama al método.