Excepciones en Java

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

Curso de Java

11.  
22.  

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.

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);

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.

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..

Ejercicio: comparar fechas

Implementar una clase Persona, con los siguientes campos:
String dni
String nombre
Date fechaNacimiento

Se considerará que dos instancias de Persona son iguales si tienen el mismo dni.

Implementar una clase Servicios con los siguientes métodos:

  • getPersonaMayor: Recibe un mapa de personas personas y devuelve la persona mayor. Arroja una SinDatosException si el mapa está vacío (isEmpty()).
    Para comparar las fechas de los objetos de la clase Date:
  • El método getTime() me devuelve los milisegundos de la fecha.
  • Los métodos after() y before() me devuelven true o false dependiendo de que fecha fue anterior.
  • getPrimerNombre: Recibe un mapa igual al anterior y devuelve la persona con el primer nombre en orden alfabético. Arroja una SinDatosException si el mapa está vacío. Desde este método llamaremos al método compareTo().

Implementar una clase Main con un método public static void main que crea dos objetos y realiza entre ellos las comparaciones antes indicadas. También debe indicarnos si dichas personas son iguales.

Para convertir una fecha en un objeto de tipo Date: 
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
Date fecha = formatter.parse(stringFecha)

Esto es MM mayúscula, las minúsculas son para minutos.

Ver preguntas de excepciones

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.