Curso básico de Java - #20 - Excepciones: Control (try-catch y throws)

Buenas mis apreciados amigos.
En este tema empezaremos a ver de una manera mas practica todo esto de las excepciones, concretamente como se controlan usando las estructuras try-catch y throws, ademas, también veremos como interactuar con estas mediante sus métodos.


Obligación de control
Como dije en el anterior tema:

La clase Exception y todas las clases que heredan de ella deben ser manejadas obligatoriamente para que el programa compile.
Y la clase RuntimeException (la cual hereda de Exception) y todas las clases que heredan de ella no tienen porque ser manejadas obligatoriamente, siendo opcional.


Jerarquía de las excepciones
Como explique en el anterior tema:

Las excepciones son como una patata caliente; se van pasando desde donde se originan a los métodos y clases llamadoras hasta llegar al método main de nuestro programa, si escala del método main y no se trata antes, el programa se rompe.

Ahí es donde entra la estructura try-catch:


Try - catch
Permite controlar una excepción y no dejar que se eleve mas.
Esta compuesto de 2 o mas bloques:

  • El bloque try el cual contiene el código el cual controlar.
  • El bloque (o bloques) catch el cual se encarga de “atrapar” la excepción y ejecutar el código “de por si acaso”.
  • Y el bloque finally el cual se encarga de ejecutar un bloque de código común independientemente de si ha saltado o no una excepción y de cual sea esta.
    Este bloque, al contrario que los anteriores, es opcional.
Sintaxis
try
{
    // Código a manejar.
}
catch ([ExceptionTipe] [variable])
{
    // Código a ejecutar en caso de error.
}
[Todos los catch que se quieran]
finally
{
    // Código común que se ejecutara en cualquier caso.
}

La variable donde se guardara la excepción usualmente se nombra como ‘e’.

Ejemplo único catch
public static void main(String[] args)
{
	Scanner entrada = new Scanner(System.in);
	
	try
	{
		entrada.nextInt();
	}
	catch (InputMismatchException e)
	{
		System.out.println("! Error: La entrada no es un numero entero.");
	}
	finally
	{
		System.out.println("Código común.");
	}

	entrada.close();

    System.out.println("El programa sigue ejecutándose.");
}

Si la excepción que salta no se contempla en el catch, esta no se podrá tratar y ocurrirá lo antes descrito. Por eso usamos varios catchs:

Ejemplo múltiples catch
public static void main(String[] args)
{
	Scanner entrada = new Scanner(System.in);
	
	try
	{
		entrada.nextInt();
	}
	catch (InputMismatchException e)
	{
		System.out.println("! Error: La entrada no es un numero entero.");
	}
	catch (NoSuchElementException e)
	{
		System.out.println("! Error: No es se ha encontrado ningún dato para leer.");
	}
	catch (IllegalStateException e)
	{
		System.out.println("! Error: No es posible invocar el metodo Scanner.nextInt() .");
	}
	catch (Exception e)
	{
		System.out.println("! Error: Excepción desconocida.");
	}
	finally
	{
		System.out.println("Código común.");
	}
	
	entrada.close();
	
	System.out.println("El programa sigue ejecutándose.");
}

Cuando hay varios catch, se empiezan a comprobar de arriba a abajo, es por eso que he puesto la excepción Exception la ultima, porque todas las excepciones heredan de esta, y por lo tanto, siempre serán atrapadas por el catch.


Throws
Sirve para “Avisar” que un metodo puede lanzar una excepción, bien porque no se controla o bien porque se crea en ese metodo.

Esta sentencia solo es obligatoria, al igual que con try - catch cuando la excepción a controlar sea heredera de Exception y no de RuntimeException. Aunque, siempre es posible ponerla.

Sintaxis
[definición del metodo] throws [TipoDeExcepción]
{
    [cuerpo del metodo]
}
Ejemplo
public void MiMetodo() throws Excepcion
{
	Scanner entrada = new Scanner(System.in);
	
	entrada.nextInt();
	
	entrada.close();
	
	System.out.println("El programa sigue ejecutándose.");
}

La excepción no se controla, solo se maneja; si salta una excepción el metodo se terminara y se pasara al metodo llamador.
Si salta una excepción en la linea entrada.nextInt();, la linea System.out.println("El programa sigue ejecutándose."); nunca se ejecutara.


En el siguiente tema seguiremos con las excepciones; veremos como sacar información de excepciones capturadas utilizando características de POO (métodos). Ademas, veremos también un ejemplo mas completo.