Las excepciones propias

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1054 bytes)next.gif (998 bytes)

Las excepciones

La clase que describe la excepción

El método que puede lanzar una excepción

Captura de las excepciones

Una función que que puede lanzar varias excepciones


El lenguaje Java proporciona las clases que manejan casi cualquier tipo de excepción. Sin embargo, podemos imaginar situaciones en la que producen excepciones que no están dentro del lenguaje Java. Siguiendo el ejemplo de la página anterior estudiaremos una situación en la que el usuario introduce un valor fuera de un determinado intervalo, el programa lanza un excepción, que vamos a llamar ExcepcionIntervalo.

 

La clase que describe la excepción

disco.gif (1035 bytes) excepcion3: ExcepcionIntervalo.java, ExcepcionApp3.java

Para crear y lanzar una excepción propia tenemos que definir la clase ExcepcionIntervalo derivada de la clase base Exception.

public class ExcepcionIntervalo extends Exception {
    public ExcepcionIntervalo(String msg) {
        super(msg);
    }
}

La definición de la clase es muy simple. Se le pasa un string msg, que contiene un mensaje, en el único parámetro que tiene el constructor de la clase derivada y éste se lo pasa a la clase base mediante super.

 

El método que puede lanzar una excepción

La función miembro que lanza una excepción tiene la declaración habitual que cualquier otro método pero se le añade a continuación la palabra reservada throws seguido de la excepción o excepciones que puede lanzar.

     static void rango(int num, int den)throws ExcepcionIntervalo{
        if((num>100)||(den<-5)){
            throw new ExcepcionIntervalo("Números fuera del intervalo");
        }

Cuando el numerador es mayor que 100 y el denominador es menor que 5 se lanza throw una excepción, un objeto de la clase ExcepcionIntervalo. Dicho objeto se crea llamando al constructor de dicha clase y pasándole un string que contiene el mensaje "Números fuera del intervalo".

 

Captura de las excepciones

Al programa estudiado en la página anterior, añadimos la llamada a la función rango que verifica si los números están dentro del intervalo dado, y el bloque catch que captura la excepción que puede lanzar dicha función si los números no están en el intervalo especificado.

public class ExcepcionApp3 {
    public static void main(String[] args) {
        String str1="120";
	String str2="3";
        String respuesta;
	int numerador, denominador, cociente;
        try{
            numerador=Integer.parseInt(str1);
            denominador=Integer.parseInt(str2);
            rango(numerador, denominador);
            cociente=numerador/denominador;
            respuesta=String.valueOf(cociente);
        }catch(NumberFormatException ex){
            respuesta="Se han introducido caracteres no numéricos";
        }catch(ArithmeticException ex){
            respuesta="División entre cero";
        }catch(ExcepcionIntervalo ex){
            respuesta=ex.getMessage();
        }
        System.out.println(respuesta);
    }

     static void rango(int num, int den)throws ExcepcionIntervalo{
        if((num>100)||(den<-5)){
            throw new ExcepcionIntervalo("Números fuera de rango");
        }
    }
}

Como vemos el numerador que vale 120 tiene un valor fuera del intervalo especificado en la función rango, por lo que se lanza una excepción cuando se llega a la llamada a dicha función en el bloque try. Dicha excepción es capturada por el bloque catch correspondiente a dicha excepción, y se ejecutan las sentencias de dicho bloque. En concreto, se obtiene mediante getMessage el texto del mensaje que guarda el objeto ex de la clase ExcepcionIntervalo.

El ciclo de vida de una excepción se puede resumir del siguiente modo:

  1. Se coloca la llamada a la función susceptible de producir una excepción en un bloque try...catch
  2. En dicha función se crea mediante new un objeto de la clase Exception o derivada de ésta
  3. Se lanza mediante throw el objeto recién creado
  4. Se captura en el correspondiente bloque catch
  5. En este bloque se notifica al usuario esta eventualidad imprimiendo el mensaje asociado a dicha excepción, o realizando una tarea específica.

 

Una función que que puede lanzar varias excepciones

disco.gif (1035 bytes) excepcion4: ExcepcionIntervalo.java, ExcepcionApp4.java

Hay otra alternativa para el ejercicio anterior, que es la de definir una función denominada calcular, que devuelva el cociente entre el numerador y el denominador, cuando se le pasa los strings obtenidos de los respectivos controles de edición. La función calcular, convierte los strings en números enteros, verifica el rango, calcula y devuelve el cociente entre el numerador y el denominador,

public class ExcepcionApp4 {
    public static void main(String[] args) {
        String str1="20";
	String str2="2";
        String respuesta;
	int numerador, denominador, cociente;
        try{
            cociente=calcular(str1, str2);
            respuesta=String.valueOf(cociente);
        }catch(NumberFormatException ex){
            respuesta="Se han introducido caracteres no numéricos";
        }catch(ArithmeticException ex){
            respuesta="División entre cero";
        }catch(ExcepcionIntervalo ex){
            respuesta=ex.getMessage();
        }
        System.out.println(respuesta);
    }
     static int calcular(String str1, String str2)throws ExcepcionIntervalo, 
		NumberFormatException, ArithmeticException{
        int num=Integer.parseInt(str1);
        int den=Integer.parseInt(str2);
        if((num>100)||(den<-5)){
            throw new ExcepcionIntervalo("Números fuera del intervalo");
        }
        return (num/den);
    }
}

Vemos que la función calcular puede lanzar, throws, tres tipos de excepciones. En el cuerpo de la función se crea, new, y se lanza, throw, explícitamente un objeto de la clase ExcepcionIntervalo, definida por el usuario, e implícitamente se crea y se lanza objetos de las clases NumberFormatException y ArithmeticException definidas en el lenguaje Java.

La sentencia que llama a la función calcular dentro del bloque try puede producir alguna de las tres excepciones que es capturada por el correspondiente bloque catch.

Podemos simplificar algo el codigo ahorrándonos la variable temporal cociente, escribiendo en vez de las dos sentencias

           cociente=calcular(str1, str2);
           respuesta=String.valueOf(cociente); 

Una única sentencia

            respuesta=String.valueOf(calcular(str1, str2));