Qué son las excepciones en Java

Qué son las excepciones en Java

Siguiendo nuestro curso de programación en este artículo vamos a indagar más en en la gestión de excepciones en Java. Como ya hemos visto debido a la falta de mecanismos para la gestión de los errores de ejecución, Java incorpora el manejo de excepciones en tiempo de ejecución. Cuando se detecta un error en tiempo de ejecución, se debe lanzar una excepción, tenemos que tener claro que:

introduccion_excepciones_java

  • Las excepciones son objetos derivados de la clase Exception.
  • Java ofrece diferentes excepciones para ser utilizadas por el programador.
  • Nuevos tipos de excepciones (clases) también pueden ser añadidos por parte del programador.

Las excepciones son un mecanismo de tratamiento de errores, disponible en diversos lenguajes orientados a objetos como: Java, C++, C# o Smalltalk entre muchos.

Excepciones en Java

Las excepciones son lanzadas con la palabra reservada throw. Por ejemplo, supongamos que añadimos el siguiente método a nuestra clase Granja:

public Animal verAniamal(int index) {    if (index < 0 || index >= this.animales.size())        throw new IllegalArgumentException("Indice fuera de los límites");    return animales.get(index);}

Si ejecutamos el siguiente código:

Granja g = new Granja("granja1");g.verAniamal(-1);

Tendremos una salida similar a:error_indice_incorrecto

Por tanto, la ejecución anterior produce una excepción no capturada (no controlada). Bajo estas circunstancias, el programa termina anormalmente y nos muestra información sobre el error.

Debemos dar nos cuenta que si el lanzamiento de una excepción es la manera más efectiva que tiene un objeto para indicar que no puede completar la solicitud del cliente. El flujo normal de ejecución es interrumpido y tenemos que:

  • Usa un tipo especial de retorno que el cliente no puede ignorar (el cliente no puede ignorar los errores).
  • Se ponen en marcha los mecanismos específicos de recuperación de errores.

En el ejemplo observamos que cuando no se cumpla la condición que queremos se el programa lanzará la excepción:

throw new IllegalArgumentException("Indice fuera de los límites");

Java proporciona una clase Exception de la que heredan todas las demás excepciones. Es importante que el programador sepa que instrucción lanzar, ya que cada instrucción se debe lanzar en el momento cuando realmente se produzca.

La clase Exception

La clase Exception es una clase proporcionada por la API de Java que posee las siguientes definiciones del constructor:

constructor_clase_exception

Como observamos cuando creamos un nuevo objeto Excepcion podemos asignarle, si queremos, un mensaje y una causa de porque se crea. Casi siempre se suele crear indicándole un mensaje para que se muestre por pantalla cuando se genere. En nuestro ejemplo eso es lo que hacemos.

Subclases más importantes

Son muchas clases y muy usadas. Podéis consultarlas aquí

La más destacable quizás sea la NullPointerException que es la que más ligada va a problemas relacionados con la orientación a objetos y que básicamente se debe a estar utilizando un objeto null como si no lo fuese, por ejemplo llamar un método get de un objeto null.

Redefiniendo nuevas clases

A veces nos pasa que nuestro programa genera excepciones que son únicas, o que nosotros pensamos que son únicas y que deben tratarse de una forma diferente. Como esto es orientación a objetos, podemos redefinir una nueva clase que herede de la clase Exception y lanzarla cuando consideremos que cometamos el error.

Por ejemplo vamos a definir la siguiente clase:

public class ProgramException extends Exception {public void animalNull() {    System.err.println("Objeto null en la lista");}public void fueraIndices() {    System.err.println("Fuera de los indices se devolvera un null");    }}

Modificamos los siguientes métodos en la clase Granja:

public void añadirAnimal(Animal animal) throws ProgramException {    if (animal == null)        new ProgramException().animalNull();    else        animales.add(animal);}public Animal verAniamal(int index) {    if (index < 0 || index >= this.animales.size()) {        new ProgramException().fueraIndices();        return null;    }    return animales.get(index);}

Ejecutamos el lanzador con:

public static void main(String[] args) throws ProgramException {    Granja g = new Granja("granja1");    g.verAniamal(-1);    g.añadirAnimal(null);}

Si nos fijamos nosotros en realidad no estamos lanzando una excepción cuando cometamos el error si no antes creando un objeto de tipo ProgramException y desde el objeto lanzamos el un método que nos muestra el mensaje asociado. Esto no es para nada habitual incluso es hasta un poco incoherente crear una nueva clase y llamar a sus métodos para simplemente lanzar un mensaje, esto tendría sentido si realizásemos más cosas. Lo normal seria definir la clase ProgramException como:

public class ProgramException extends Exception {public ProgramException(String e) {    super(e);}public String getMessage() {    return super.getMessage();}   // aqui podriamos incluir codigo adicional para el tratamiento}

Modificamos los siguientes métodos en la clase Granja:

public Animal verAniamal(int index) throws ProgramException {    if (index < 0 || index >= this.animales.size()) {        throw new ProgramException("excepcion por indice negativo");    } else {        return animales.get(index);    }}public void añadirAnimal(Animal animal) throws ProgramException {    if (animal == null)        throw new ProgramException("excepcion por animal null");    else        animales.add(animal);}

Ejecutamos el lanzador con:

public static void main(String[] args) {Granja g = new Granja("granja1");try {    g.añadirAnimal(null);} catch (ProgramException e) {         System.out.println(e.getMessage());}try {    g.verAniamal(-1);} catch (ProgramException e) {    System.out.println(e.getMessage());}System.out.println("Yo me ejecuto porque se trata la excepcion");}

o también lo podemos definir como:

public static void main(String[] args) {Granja g = new Granja("granja1");try {    g.añadirAnimal(null);            g.verAniamal(-1);} catch (ProgramException e) {         System.out.println(e.getMessage());}System.out.println("Yo me ejecuto porque se trata la excepcion");}

Aunque esto último solo lanzará el mensaje de error por añadir un objeto null.

Los errores los capturamos en los métodos donde se cometen y luego donde se llaman a estos métodos es donde se añade el código para tratar la excepción. El tratamiento de excepciones por lo general siempre se suele utilizar las clases definidas en el lenguaje, aunque en proyectos grandes se suele tener una serie de clases que trabajan con excepciones.

Como siempre aquí podéis descargar el código y probarlo vosotros mismos.

Para ti
Queremos saber tu opinión. ¡Comenta!