Manejo de Errores Usando Excepciones Java

El trmino excepcin es un forma corta da la frase "suceso excepcional" y puede definirse de la siguiente forma.

Definicin:

Una excepcin es un evento que ocurre durante la ejecucin del programa que interrumpe el flujo normal de las sentencias.

Muchas clases de errores pueden utilizar excepciones -- desde serios problemas de hardware, como la avera de un disco duro, a los simples errores de programacin, como tratar de acceder a un elemento de un array fuera de sus lmites. Cuando dicho error ocurre dentro de un mtodo Java, el mtodo crea un objeto 'exception' y lo maneja fuera, en el sistema de ejecucin. Este objeto contiene informacin sobre la excepcin, incluyendo su tipo y el estado del programa cuando ocurri el error. El sistema de ejecucin es el responsable de buscar algn cdigo para manejar el error. En terminologa java, crear una objeto exception y manejarlo por el sistema de ejecucin se llama lanzar una excepcin.

Despus de que un mtodo lance una excepcin, el sistema de ejecucin entra en accin para buscar el manejador de la excepcin. El conjunto de "algunos" mtodos posibles para manejar la excepcin es el conjunto de mtodos de la pila de llamadas del mtodo donde ocurri el error. El sistema de ejecucin busca hacia atrs en la pila de llamadas, empezando por el mtodo en el que ocurri el error, hasta que encuentra un mtodo que contiene el "manejador de excepcin" adecuado.

Un manejador de excepcin es considerado adecuado si el tipo de la excepcin lanzada es el mismo que el de la excepcin manejada por el manejador. As la excepcin sube sobre la pila de llamadas hasta que encuentra el manejador apropiado y una de las llamadas a mtodos maneja la excepcin, se dice que el manejador de excepcin elegido captura la excepcin.

Si el sistema de ejecucin busca exhaustivamente por todos los mtodos de la pila de llamadas sin encontrar el manejador de excepcin adecuado, el sistema de ejecucin finaliza (y consecuentemente y el programa Java tambin).

Mediante el uso de excepciones para manejar errores, los programas Java tienen las siguientes ventajas frente a las tcnicas de manejo de errores tradicionales.

.Ventaja 1: Separar el Manejo de Errores del Cdigo "Normal"

En la programacin tradicional, la deteccin, el informe y el manejo de errores se convierte en un cdigo muy liado. Por ejemplo, supongamos que tenemos una funcin que lee un fichero completo dentro de la memeoria. En pseudo-cdigo, la funcin se podra parecer a esto.

leerFichero {
    abrir el fichero;
    determinar su tamao;
    asignar suficiente memoria;
    leer el fichero a la memoria;
    cerrar el fichero;
}

A primera vista esta funcin parece bastante sencilla, pero ignora todos aquello errores potenciales.

  • Qu sucede si no se puede abrir el fichero?
  • Qu sucede si no se puede determinar la longitud del fichero?
  • Qu sucede si no hay suficiente memoria libre?
  • Qu sucede si la lectura falla?
  • Qu sucede si no se puede cerrar el fichero?

Para responder a estas cuestiones dentro de la funcin, tendramos que aadir mucho cdigo para la deteccin y el manejo de errores. El aspecto final de la funcin se parecera esto.

codigodeError leerFichero {
    inicializar codigodeError = 0;
    abrir el fichero;
    if (ficheroAbierto) {
        determinar la longitud del fichero;
        if (obtenerLongitudDelFichero) {
            asignar suficiente memoria;
            if (obtenerSuficienteMemoria) {
                leer el fichero a memoria;
                if (falloDeLectura) {
                    codigodeError = -1;
                }
            } else {
                codigodeError = -2;
            }
        } else {
            codigodeError = -3;
        }
        cerrar el fichero;
        if (ficheroNoCerrado && codigodeError == 0) {
            codigodeError = -4;
        } else {
            codigodeError = codigodeError and -4;
        }
    } else {
        codigodeError = -5;
    }
    return codigodeError;
}

Con la deteccin de errores, las 7 lneas originales (en negrita) se han covertido en 29 lneas de cdigo-- a aumentado casi un 400 %. Lo peor, existe tanta deteccin y manejo de errores y de retorno que en las 7 lneas originales y el cdigo est totalmente atestado. Y an peor, el flujo lgico del cdigo tambin se pierde, haciendo dficil poder decir si el cdigo hace lo correcto (si se cierra el fichero realmente si falla la asignacin de memoria?) e incluso es dficil asegurar que el cdigo continue haciendo las cosas correctas cuando se modifique la funcin tres meses despus de haberla escrito. Muchos programadores "resuelven" este problema ignordolo-- se informa de los errores cuando el programa no funciona.

Java proporciona una solucin elegante al problema del tratamiento de errores: las excepciones. Las excepciones le permiten escribir el flujo principal de su cdigo y tratar los casos excepcionales en otro lugar. Si la funcin leerFcihero utilizara excepciones en lugar de las tcnicas de manejo de errores tradicionales se podra parecer a esto.

leerFichero {
    try {
           abrir el fichero;
           determinar su tamao;
           asignar suficiente memoria;
           leer el fichero a la memoria;
           cerrar el fichero;
    } catch (falloAbrirFichero) {
        hacerAlgo;
    } catch (falloDeterminacionTamao) {
        hacerAlgo;
    } catch (falloAsignaciondeMemoria) {
        hacerAlgo;
    } catch (falloLectura) {
        hacerAlgo;
    } catch (falloCerrarFichero) {
        hacerAlgo;
    }
}

Observa que las excepciones no evitan el esfuerzo de hacer el trabajo de detectar, informar y manejar errores. Lo que proporcionan las excepciones es la posibilidad de separar los detalles oscuros de qu hacer cuando ocurre algo fuera de la normal.

Adems, el factor de aumento de codigo de este es programa es de un 250% -- comparado con el 400% del ejemplo anterior.

.Ventaja 2: Propagar los Errores sobre la Pila de Llamadas

Una segunda ventaja de las exepciones es la posibilidad del propagar el error encontrado sobre la pila de llamadas a mtodos. Supongamos que el mtodo leerFichero es el cuarto mtodo en una serie de llamadas a mtodos anidadas realizadas por un programa principal: metodo1 llama a metodo2, que llama a metodo3, que finalmente llama a leerFichero.

metodo1 {
    call metodo2;
}
metodo2 {
    call metodo3;
}
metodo3 {
    call leerFichero;
}

Supongamos tambin que metodo1 es el nico mtodo interesado en el error que ocurre dentro de leerFichero. Tradicionalmente las tcnicas de notificacin del error forzaran a metodo2 y metodo3 a propagar el cdigo de error devuelto por leerFichero sobre la pila de llamadas hasta que el cdigo de error llegue finalmente a metodo1 -- el nico mtodo que est interesado en l.

metodo1 {
    codigodeErrorType error;
    error = call metodo2;
    if (error)
        procesodelError;
    else
        proceder;
}
codigodeErrorType metodo2 {
    codigodeErrorType error;
    error = call metodo3;
    if (error)
        return error;
    else
        proceder;
}
codigodeErrorType metodo3 {
    codigodeErrorType error;
    error = call leerFichero;
    if (error)
        return error;
    else
        proceder;
}

Como se aprendi anteriormente, el sistema de ejecucin Java busca hacia atrs en la pila de llamadas para encontrar cualquier mtodo que est interesado en manejar una excepcin particular. Un mtodo Java puede "esquivar" cualquier excepcin lanzada dentro de l, por lo tanto permite a los mtodos que estn por encima de l en la pila de llamadas poder capturarlo. Slo los mtodos interesados en el error deben preocuparse de detectarlo.

metodo1 {
    try {
        call metodo2;
    } catch (excepcion) {
        procesodelError;
    }
}
metodo2 throws excepcion {
    call metodo3;
}
metodo3 throws excepcion {
    call leerFichero;
}

Sin embargo, como se puede ver desde este pseudo-cdigo, requiere cierto esfuerzo por parte de los mtodos centrales. Cualquier excepcin chequeada que pueda ser lanzada dentro de un mtodo forma parte del interface de programacin pblico del mtodo y debe ser especificado en la clausula throws del mtodo. As el mtodo informa a su llamador sobre las excepciones que puede lanzar, para que el llamador pueda decidir concienzuda e inteligentemente qu hacer con esa excepcin.

Observa de nuevo la diferencia del factor de aumento de cdigo y el factor de ofuscacin entre las dos tcnicas de manejo de errores. El cdigo que utiliza excepciones es ms compacto y ms fcil de entender.

.Ventaja 3: Agrupar Errores y Diferenciacin

Frecuentemente las excepciones se dividen en categorias o grupos. Por ejemplo, podramos imaginar un grupo de excepciones, cada una de las cuales representara un tipo de error especfico que pudiera ocurrir durante la manipulacin de un array: el ndice est fuera del rango del tamao del array, el elemento que se quiere insertar en el array no es del tipo correcto, o el elemento que se est buscando no est en el array. Adems, podemos imaginar que algunos mtodos querran manejar todas las excepciones de esa categoria (todas las excepciones de array), y otros mtodos podra manejar slo algunas excepciones especficas (como la excepcin de ndice no vlido).

Como todas las excepciones lanzadas dentro de los programas Java son objetos de primera clase, agrupar o categorizar las excepciones es una salida natural de las clases y las superclases. Las excepciones Java deben ser ejemplares de la clase Throwable, o de cualquier descendiente de sta. Como de las otras clases Java, se pueden crear subclases de la clase Throwable y subclases de estas subclases. Cada clase 'hoja' (una clase sin subclases) representa un tipo especfico de excepcin y cada clase 'nodo' (una clase con una o ms subclases) representa un grupo de excepciones relacionadas.

InvalidIndexException, ElementTypeException, y NoSuchElementException son todas clases hojas. Cada una representa un tipo especfico de error que puede ocurrir cuando se manipula un array. Un mtodo puede capturar una excepcin basada en su tipo especfico (su clase inmediata o interface). Por ejemplo, una manejador de excepcin que slo controle la excepcin de ndice no vlido, tiene una sentencia catch como esta.

catch (InvalidIndexException e) {
    . . .
}

ArrayException es una clase nodo y representa cualquier error que pueda ocurrir durante la manipulacin de un objeto array, incluyendo aquellos errores representados especficamente por una de sus subclases. Un mtodo puede capturar una excepcin basada en este grupo o tipo general especificando cualquiera de las superclases de la excepcin en la sentencia catch. Por ejemplo, para capturar todas las excepciones de array, sin importar sus tipos especficos, un manejador de excepcin especificara un argumento ArrayException.

catch (ArrayException e) {
    . . .
}

Este manejador podra capturar todas las excepciones de array, incluyendo InvalidIndexException, ElementTypeException, y NoSuchElementException. Se puede descubrir el tipo de excepcin preciso que ha ocurrido comprobando el parmtero del manejador e. Incluso podramos seleccionar un manejador de excepciones que controlara cualquier excepcin con este manejador.

catch (Exception e) {
    . . .
}

Los manejadores de excepciones que son demasiado generales, como el mostrado aqu, pueden hacer que el cdigo sea propenso a errores mediante la captura y manejo de excepciones que no se hubieran anticipado y por lo tanto no son manejadas correctamente dentro de manejador. Como regla no se recomienda escribir manejadores de excepciones generales.

Como has visto, se pueden crear grupos de excepciones y manejarlas de una forma general, o se puede especificar un tipo de excepcin especfico para diferenciar excepciones y manejarlas de un modo exacto.

. Y ahora qu?

Ahora que has entendido qu son las excepciones y las ventajas de su utilizancin en los programas Java, es hora de aprender cmo utilizarlas.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

HAY 1 COMENTARIOS
  • Anónimo dijo:

    Felicitaciones esta ecelente toda esta info...gracias me han ayudado mucho.

Conéctate o Regístrate para dejar tu comentario.