Curso de Java | Excepciones 1

Curso de Java
Excepciones

Curso de Java | Excepciones 2

Una excepción es un problema que aparece o podría aparecer durante la ejecución del programa

Tipos de excepciones

  • En tiempo de compilación (checked exceptions): Heredan de java.lang.Exception. El compilador nos obligará a controlarlas mediante un bloque Try/Catch o un throws.
  • En tiempo de ejecución (unchecked exceptions): Heredan de java.lang.RuntimeException. Es la única Exception que no es comprobada por el compilador. Un error también se produce en tiempo de ejecución, aunque un error no es una excepción.
excepciones en java

Excepción con un catch

System.out.println("antes");
try{
 System.out.println(2/0);
}catch (ArithmeticException e){
 System.out.println("en catch");
 e.printStackTrace();
}
System.out.println("después");

Output:
antes
en el try
en el catch
java.lang.ArithmeticException
después

Excepción con varios catch

System.out.println("antes");
try{
 System.out.println("en el try");
 System.out.println(2/0);
}catch (ArithmeticException e){
 System.out.println("en catch1");
 e.printStackTrace();
}catch(Exception e){
 System.out.println("en catch2");
 e.printStackTrace();
}catch(Throwable t){
 System.out.println("en catch3");
 t.printStackTrace();
}
System.out.println("despues");

El único catch que se aplica es el que recoge la excepción. Después de este, el programa continua ejecutándose a partir del último Catch.

Para que el código compile, los tipos de Error más generales(Throwable) deben estar por debajo de los más particulares(ArithmeticException)

Throw

public class ArrojarExcepcion {
 public static void main(String[] args) {
  ArrojarExcepcion arrojarExcepcion = new ArrojarExcepcion();
   try {
   arrojarExcepcion.lanzarExcepcion();
  } catch (Exception e) {
   System.out.println("excepción lanzada y procesada");
  }
  arrojarExcepcion.procesarExceptionInSitu();
 }
 public void lanzarExcepcion() throws Exception{
  throw new Exception();
 }
 public void procesarExceptionInSitu(){
  try {
   throw new Exception();
  } catch (Exception e) {
   System.out.println("excepción procesada");
  }
 }
}

Consola:
excepción lanzada y procesada
excepción procesada

Finally

El finally se ejecuta siempre, se trate la excepción o no se trate la excepción. La única forma de evitar que se ejecute el finally es ejecutando un System.exit(), que mata la máquina virtual.

Se utiliza siempre en conjunción con un try-catch. No puede haber nada después del catch y antes del finally.

public static void main(String[] args) {
 int i = 2;
 int j = 0;
 System.out.println("antes");
 try{
  System.out.println(i/j);
 }catch (ArithmeticException e){
  System.out.println("en catch1");
  e.printStackTrace();
 }catch(Exception e){
  System.out.println("en catch2");
 }catch(Throwable t){
  System.out.println("en catch3");
 }finally{
  System.out.println("en finally");
 }
 System.out.println("después");
}

Output:
antes
en catch1
java.lang.ArithmeticException
en finally
después

Crear una excepción

Asistente para crear excepciones en Java

Personalizar el mensaje de error de la excepción

Al instanciar la excepción podemos pasarle al constructor de la misma una cadena de texto con información sobre el estado de las variables en el momento en que se ha producido.

throw new MiPropiaException("Excepción lanzada. a:"+a+ "b: "+b);
public class MiPropiaException extends Exception{
   MiPropiaException(String errorMsg){
      super(errorMsg);
   }
}

Este constructor alimentará la propiedad message de la Exception.

Para imprimir el mensaje de error en el momento de capturar la excepción:

}catch(MiPropiaException e){
 System.err.println(e.getMessage());
 e.printStackTrace(); // Para saber la línea en la que se ha producido la excepción
}

System.out hace la referencia a la salida estándard. System.err hace referencia a la salida de errores. En eclipse, la salida de errores System.err se muestra en rojo.

Como son salidas diferentes, es posible personalizaras para que, por ejemplo, la salida de errores se produzca a un fichero de texto en lugar de a la consola.

Si queremos personalizar el mensaje que mostrará la llamada al método printStackTrace podemos utilizar un código similar a este:

public void printStackTrace() {
    for (StackTraceElement element : getStackTrace()) {
        System.err.println(
            "Clase: " + element.getClassName() +
            ", Método: " + element.getMethodName() +
            ", Archivo: " + element.getFileName() +
            ", Línea: " + element.getLineNumber()
        );
    }
}

Ejercicios

Ejercicio: excepciones

Implementar una clase Main que llame un método getPrecioConIva() e imprima el valor que devuelve.

Este método getPrecioConIva() que recibirá un número y devolverá dicho número multiplicado por 1.16. Si el precio es mayor que 100 arrojará una PrecioDemasiadoAltoException que será capturada en el Main.

Implementar una clase PrecioDemasiadoAltoException y hacer que cuando la excepción se produczca se muestre un mensaje de error personalizado que indique a cuanto ascendió el precio con IVA que originó la excepción. Para lograr esto, llevar a cabo dos acciones:

  • Sobreescribir el método printStackTrace().
  • Alimentar el mensaje del error utilizando el contructor de la construcción que hemos lanzado.

La excepción capturada se vería así:

catch(PrecioDemasiadoAltoException e){
 System.err.println(e.getMessage());
 e.printStackTrace();
}

Ejercicio: comparar fechas

Implementar una clase Persona, con los siguientes campos:

String dni
String nombre
Date fechaNacimiento

Para convertir una fecha en un objeto de tipo Date:

SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); // MM debe estar en mayúscula, las minúsculas son para minutos.
Date fecha = formatter.parse("10-11-2024");

Implementar una clase Servicios que tenga un méotodo getPersonaMayor que recibirá una colección de personas y devolverá la persona mayor. Para ello, sobreescribiremos el compareTo de la clase Persona.
Esta función arrojará una SinDatosException si la colección está vacío (isEmpty()).

Para comparar las fechas de los objetos de la clase Date ten en cuenta que esta clase ya tiene integrado un compareTo.

Ver preguntas de la certificación