Java para programadores – Las excepciones

Aunque intentamos explicar como programar en java sin cometer errores, somos conscientes que esa perfección nunca la conseguiremos; que nuestros programas tendrán errores, y, cuando los corrijamos, quedaran los usuarios, si, esos entes que tienen la capacidad de encontrar el único agujero que nos quedó,  y hacer, que todo nuestro castillo de naipes (aplicación), se venga al suelo de una manera vergonzosa. Y es por todo ello, que necesitamos que nuestro programa sea capaz de enterarse de los errores que aparecen, y procesarlos.

Las listas de errores

Primero de todo, tengamos en cuenta los dos grandes grupos de excepciones que podemos maneja:

Por un lado, tenemos el grupo de las  “Unchecked exceptions“. En este apartado se engloban las excepciones que provienen de errores de programación, y que no estamos obligados a manejar; dejando que sea la máquina virtual la que se encargue de ello:

Excepción Descripción
ArithmeticException Error aritmetico; Ej: división por cero
ArrayIndexOutOfBoundsException Indice de array fuera de rango. Se esta intentando acceder a un array con un indice mayor que el tamaño del array, o menor de 0
ArrayStoreException Se intenta guardar en un array un tipo incompatible
ClassCastException Cast invalido
IllegalArgumentException Llamada a un módulo con un argumento ilegal
IllegalMonitorStateException Funcionamiento del monitor ilegal, como la espera de un subproceso desbloqueado.
IllegalStateException Entorno o aplicación en un estado erroneo
IllegalThreadStateException La operación solicitada, no es compatible con el estado del proceso
IndexOutOfBoundsException Algun indice está fuera de rango
NegativeArraySizeException Array creado con un tamaño negativo
NullPointerException Uso invalido de la referencia null
NumberFormatException Conversion de string a numero, erronea
SecurityException Intento de violación de seguridad
StringIndexOutOfBounds Intento de acceso a una posición de string que no existe
UnsupportedOperationException Se ha encontrado una operación no soportada

En el segundo grupo, tenemos las “Checked exceptions”, que son las que suceden por hechos ajenos al funcionamiento normal del programa. La mayoría de ellas, están relacionadas con la entrada salida, o con la adquisición de valores erróneos. Estas, java nos obliga a tenerlas en cuenta, capturandolas, o pasándoselas al método superior de forma explicita, hasta que llegue a la máquina virtual:

Excepcion Descripcion
ClassNotFoundException La clase no existe
CloneNotSupportedException Intento de clonar un objeto que no implementa la interfaz Cloneable
IllegalAccessException Acceso a la clase, denegado
InstantiationException Intento de crear un objeto desde una clase no instanciable
InterruptedException Un subproceso, ha sido interrumpido por otro subproceso
NoSuchFieldException el campo solicitado, no existe
NoSuchMethodException El método solicitado, no existe

Capturando los mensajes de excepción

Para poder capturar la excepción, en java, tenemos la posibilidad de rodear las zonas en donde se pueda generar  con la estructura :

try {

 instrucciones a mantener bajo control

}

catch  (Exception e){

instrucciones a ejecutar en caso de error

}

finally {

instrucciones a ejecutar siempre, aunque se produzca error

}

 Si revisamos estos bloques, tenemos :

El try inicia el bloque de instrucciones que se deben ejecutar normalmente y en las que se puede producir algún error.

El catch inicia los bloques en los que se maneja la excepción, y deberemos indicarle qué excepción queremos manejar. Podremos poner tantos bloques catch como excepciones tengamos que manejar:

try {
    ...........
    instrucciones a ejecutar, que pueden causar alguna excepción
    ............
} catch (IndexOutOfBoundsException e) {
     ...............
    instrucciones para manejar la IndexOutOfBoundsException..
     ...........
} catch (IOException e) {
    .............
    instrucciones para manejar otra excepción (en este caso, cualquier otra excepción, ya que Exception es genérico.
    .............
}

Por último, la clausula finally, representa un bloque por el que se ha de pasar siempre. Haya o no haya error. Normalmente se utilizará para liberar recurso, o cerrar ficheros…

} finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        } 
        else {
            System.out.println("PrintWriter not open");
        }
    }

A partir de Java 7, cuando el motivo es cerrar conexiones, podemos ahorrarnos el finally, especificando los recursos a cerrar a continuación de la clausula try

 try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }

Cabe destacar que no es necesario codificar catch, si no queremos capturar una excepción, aun así. podemos seguir utilizando finally para realizar algún proceso que se requiera aunque el try salga por error:

 BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }

Aunque, por ejemplo, en este caso, deberemos especificar que nuestro método genera una excepción, ya que si no la capturamos nosotros, deberemos dejar que pase:

static String read(String path) throws IOException {

Generando/lanzando excepciones

Puede haber ocasiones, en que nos interese lanzar una excepción desde nuestro código. Para hacerlo, disponemos de una instrucción:

throw new laExcepcion

Para poderlo hacer, utilizaremos un objeto ya existente que herede de java.lang.Throwable

Creando nuevas excepciones

Si podemos lanzar excepciones, también es interesante que podamos crearlas y no tener que depender únicamente de las que nos proporciona Java.

Para crear una excepción, solo tenemos que definir una clase que herede de Exception  o RuntimeException.

Deberemos preparar el constructor por defecto, y un segundo constructor que reciba un atributo String describiendo la razón de la excepción

Por ejemplo, esta clase podría ser una nueva excepción:

public class SaldoInsuficiente
      extends RuntimeException {

     publicSaldoInsuficiente() {}

     public SaldoInsuficiente(String message) { 
           super(message); 
     } 
}

 

Acerca de Miguel Garcia

Programador, Desarrollador web, Formador en distintas areas de informatica y director de equipos multidisciplinares.
Esta entrada fue publicada en Formacion, Java. Guarda el enlace permanente.

Deja un comentario