Excepciones

Ya somos unos grandes programadores
Pero que pasa si en la ejecución ...

Houston, tenemos un problema!!

http://history.nasa.gov/alsj/a13/images13.html

Para eso tenemos las excepciones

Excepciones

¿Qué hacer cuando ocurre un error?

  • Cuando una operación no puede completarse, el programa puede:
    • Volver al estado anterior y continuar las operaciones que pueda realizar
    • Guardar su estado y finalizar.
    • Interrumpir su ejecución y cerrarse.
  • Para poder hacer esto, es necesario detectar el error y mandar la información al que pueda manejarlo.

Excepciones

¿Qué hacer cuando ocurre un error?

  • Tradicionalmente se devolvía códigos de error
    • Tradicionalmente 0 si la ejecución acaba correctamente.
    • El código retornado determina el tipo de error producido.
  • Sin embargo, tiene una serie de problemas:
    • No tiene porqué consultarse.
    • Contemplar todos los errores puede complicar la legibilidad del código.
  • Esto puede hacer que nos perdamos errores.

Excepciones

¿Qué es una excepción?

  • Es un evento excepcional que ocurre durante la ejecución del programa.
  • Interrumpe el flujo normal de las sentencias.
  • Crea un objeto Throwable que envía al método que lo ha generado.
  • Este objeto facilita información sobre el error ocurrido.

Excepciones

¿Qué es una excepción?

  • Simplifican los programas ya que se separa el código normal y el de la gestión de errores.
  • Se deben usar cuando no se puede resolver la situación en el mismo contexto.
  • No exime de seguir haciendo el control de los errores.
  • Este objeto facilita información sobre el error ocurrido.

Excepciones

Tipos de situaciones excepcionales

  • Los errores suelen ser situaciones de las que no se puede recuperar.
  • Ejemplos:
    • Clase no encontrada.
    • Memoria agotada.
    • No se localiza el main.
  • No se suele tener que proporcionar tratamiento para ellos.

Excepciones

Tipos de situaciones excepcionales

  • Las excepciones son situaciones que impiden completar la ejecución correcta.
  • Ejemplos:
    • Fichero no encontrado.
    • Tiempo de conexión agotado.
  • Debéis de tratarlos y continuar con el flujo de ejecución del programa, en la medida que sea posible.

Excepciones

Tipos de situaciones excepcionales

Excepciones

Gestión de excepciones

  • Cuando se da una condición especial, se lanza una excepción.
  • Esta se lanza con el comando throw:
  •                     if ("error de CRC"){
                           throw new IOException();
                        }
                 
  • La clase de la excepción contiene toda la información necesaria para el tratamiento de la misma.

Excepciones

Gestión de excepciones

  • Un método también puede indicar qué puede fallar.
  • Se utiliza la palabra reservada throws:
  • 
                    void f() throws EOFException, FileNotFoundException{
                        if ( ... )
                            throw new EOFException();
                        if ( ... )
                            throw new EOFException
                    }
    
                 
  • La clase de la excepción contiene toda la información necesaria para el tratamiento de la misma.

Excepciones

Manejo de las excepciones

  • Hay que indicar quién trata la excepción.
  • Para ello se utilizan las palabras reservadas try y catch.
    • try delimita el grupo de sentencias que pueden producir las excepciones.
    • catch delimita el tratamiento que se le da a la excepción.

Excepciones

Manejo de las excepciones

  • Suele tener este esquema.
  • 
                    try{
                       // Operaciones que pueden producir una excepción
                    }
                    catch( TipoDeExcepcion ref ){
                       // Tratamiento de la excepción
                    }
    
                 

Excepciones

Manejo de las excepciones

  • Aquí tenemos un ejemplo.
  •                 try{
                       a.abrirFichero();
                       a.leeCabecera();
                       a.actualizaDatos();
                    }
                    catch( FileNotFoundException e ){
                       System.out.println("Error de apertura: " + e.message());
                    }
                    catch( IOException e ){
                       System.out.println("Error de E/S: " + e.message());
                    }
                 

Excepciones

Manejo de las excepciones

  • Si se produce una excepción que no se corresponde con ningún catch indicado, la excepción se propaga hacia atrás en la secuencia de invocaciones hasta encontrar un catch adecuado.

Excepciones

Manejo de las excepciones

  • Ejemplo. ¿Qué sucede en este código?:
  •               void f1( int accion ) throws EOFException{
                    try{
                      if( accion == 1 )
                        throw new FileNotFoundException();
                      else if( accion == 2 )
                        throw new EOFException();
                    }
                    catch( FileNotFoundException e ){
                      System.out.println( "Error corregido" );
                    }
                    System.out.println("Finalización normal de f1");
                  }
                  void f2( int accion ){
                    try{
                      f1( accion ):
                    }
                    catch( EOFException e ){
                      System.out.println( "Error corregido" );
                    }
                    System.out.println("Finalización normal de f2");
                  }
                 

Excepciones

Manejo de las excepciones

  • Es decir, cuando se invoca un método que lanza excepciones se pueden hacer dos cosas.
    • Manejar el error a través de un catch.
    • Indicar mediante un throws su propagación hacia el método que le llama.

Excepciones

Finally

  • Hay ocasiones en las que se quiere ejecutar un fragmento de código, independientemente de que se haya dado una excepción o no.
  • Para ello se utiliza la cláusula finally.
  • Esta cláusula se añade al final de la lista de excepciones capturadas:
                    try{
                      // Operaciones posibles
                    }
                    catch( Exception e ){
                      // Tratamiento de la excepción
                    }
                    finally{
                      // Operaciones comunes a ambas.
                    }
    
                 

Excepciones

Flujo de ejecución

  • Si no se produce ningún error, se ejecutan los bloques de try y finally.
  • Si se produce algún error:
    • Si la excepción es atrapada por un catch del mismo try: se ejecuta primero el bloque catch y luego el bloque finally.
    • Si no es atrapada, se ejecuta el bloque finally y la excepción se propaga al contexto anterior.

Excepciones

Relanzar excepciones

  • Hay situaciones en las que interesa relanzar las excepciones ya atrapadas.
  • Se da un tratamiento a una excepción pero es necesario (o interesante) seguir propagando la excepción hacia arriba, para que el contexto superior siga teniendo constancia de ella.
  • Por ejemplo, existe un problema con la conectividad. Mi clase trata el problema pero quiere informar a la clase que le ha llamado que existe un problema de red.

Excepciones

Relanzar excepciones

  • Se haría de la siguiente manera:
                    try{
                      // Operaciones posibles
                    }
                    catch( Exception e ){
                      // Tratamiento de la excepción
                      throw e;
                    }
                 

Tipos de excepciones

  • Implícitas
    • Se producen por errores de programación.
    • Heredan de RunTimeException.
    • Hay que corregir el error.
    • Ej: cast incorrecto, acceso a array fuera de rango, ...
  • Explícitas
    • Indican error ajeno al programa.
    • Heredan de Exception.
    • Hay que tratarlas.
    • Ej: fichero no encontrado, sin acceso a red, ...

Creación de excepciones

  • Deben deribar de la clase Throwable
  • Normalmente heredan de RuntimeException para notificar errores de programación y de Exception en cualquier otro caso.

Obtener información de la excepción

  • Una excepción aporta información, como lo hace cualquier otra clase.
  • Lo hace a través de los siguientes métodos:
    • public String getMessage(): Devuelve un mensaje detallado con el error de la excepción.
    • public String toString(): Devuelve la representación del error en un string.
    • public void printStackTrace(): Visualiza la traza de llamadas causantes del error.

Ejercicio: ¿Cuando usar excepciones?

  • Debéis pensar e implementar tres situaciones en las que se usen excepciones.
  • Podéis utilizar algunos de los ejemplos de clases que hemos visto.
    • Ejemplos:
      • Crear una clase que sume números múltiplos de 3. Muestra un error en caso de que alguno de los números no sea múltiplo.
      • Crear una clase que gestione las convocatorias de un equipo de baloncesto. Mostrar un error en caso de que sean más de 12 miembros.
    • Cread la excepción, y probad a propagarla y gestionarla.

Referencias

  • Excepciones. Luis Garmendia Salvador
  • Tema 4 Excepciones. Andoni Eguiluz