Crear Clases de Excepciones

Cuando diseñes un paquete de clases java que colabore para proporcionar alguna función útil a sus usuarios, deberás trabajar duro para asegurarte de que las clases interactuan correctamente y que sus interfaces son fáciles de entender y utilizar.Debrías estar mucho tiempo pensando sobre ello y diseñar las excepciones que esas clases pueden lanzar.

Supon que estás escribiendo una clase con una lista enlazada que estás pensando en distribuir como freeware. Entre otros métodos la clase debería soportar estos:

objectAt(int n)
Devuelve el objeto en la posición nde la lista.
firstObject()
Devuelve el primer objeto de la lista.
indexOf(Object o)
Busca el Objeto especificado en la lista y devuelve su posición en ella.

¿Qué puede ir mal?

Como muchos programadores utilizarán tu clase de lista enlazada, puedes estar seguro de que muchos de ellos la utilizarán mal o abusarán de los métodos de la clase. También, alguna llamada legitima a los métodos de la clase podría dar algún resultado indefinido. No importa, con respecto a los errores, querráa que tu clase sea lo más robusta posible, para hacer algo razonable con los errores, y comunicar los errores al programa llamador. Sin embargo, no puedes anticipar como quiere cada usuario de sus clase enlazada que se comporten sus objetos ante la adversidad. Por eso, lo mejor que puedes hacer cuando ocurre un error es lanzar una excepción.

Cada uno de los métodos soportados por la lista enlazada podría lanzar una excepción bajo ciertas condiciones, y cada uno podría lanzar un tipo diferente de excepción. Por ejemplo:

objectAt()
lanzará una excepción si se pasa un entero al método que sea menor que 0 o mayor que el número de objetos que hay realmente en la lista.
firstObject()
lanzará una excepción si la lista no contiene objetos.
indexOf()
lanzará una excepción si el objeto pasado al método no está en la lista.
Pero ¿qué tipo de excepción debería lanzar cada método? ¿Debería ser una excepción porporcionada por el entorno de desarrollo de Java? O ¿Deberían ser excepciones propias?

Elegir el Tipo de Excepción Lanzada

Trantándose de la elección del tipo de excepción a lanzar, tienes dos opciones:
  1. Utilizar una escrita por otra persona. Por ejemplo, el entorno de desarrollo de Java proporciona muchas clases de excepciones que podrías utilizar.
  2. Escribirlas tu mismo.
Necesitarás escribir tus propias clases de excepciones si respondes "Si" a alguna de las siguentes preguntas. Si no es así, probablemente podrás utilizar alguna excepción ya escrita:
  • ¿Necesitas un tipo de excepción que no está representada por lo existentes en el entorno de desarrollo de Java?
  • ¿Ayudaría a sus usuarios si pudieran diferenciar sus excepciones de las otras lanzadas por clases escritas por por otros vendedores?
  • ¿Lanza el código más una excepción relacionada?
  • Si utilizas excepciones de otros, ¿Podrán sus usuarios tener acceso a estas excepciones? Una pregunta similar es "¿Debería tu paquete ser independiente y auto-contenedor?"

La clase de lista enlazada puede lanzar varias excepciones, y sería conveniente poder capturar todas las excepciones lanzadas por la lista enlaza con un manejador. Si planeas distribuir la lista enlazada en un paquete, todo el código relacionado debe empaquetarse junto. Así para la lista enlazada, deberías crear tu propio árbol de clases de excepciones.

El siguiente diagrama ilustra una posibilidad del árbol de clases para su lista enlazada:

LinkedListException es la clase padre de todas las posibles excepciones que pueden ser lanzadas por la clase de la lista enlazada, Los usuarios de esta clase pueden escribir un sólo manejador de excepciones para manejarlas todas con una sentencia catch como esta:

catch (LinkedListException) {
    . . . 
}
O, podrñia escribir manejadores más especializados para cada una de las subclases de LinkedListException.

Elegir una Superclase

El diagrama anterior no indica la superclase de la clase LinkedListException. Como ya sabes, las excepciones de Java deben ser ejemplares de la clase Throwable o de sus subclases. Por eso podría tentarte hacer LinkedListException como una subclase de la clase Throwable. Sin embargo, el paquete java.lang proporciona dos clases Throwable que dividen los tipos de problemas que pueden ocurrir en un programa java: Errores y Excepción. La mayoría de los applets y de las aplicaciones que escribes lanzan objetos que son Excepciones. (Los errores están reservados para problemas más serios que pueden ocurrir en el sistema.)

Teorícamente, cualquier subclase de Exception podría ser utilizada como padre de la clase LinkedListException. Sin embargo, un rápido examen de esas clases muestra que o son demasiado especializadas o no están relacionadas con LinkedListException para ser apropiadas. Asi que el padre de la clase LinkedListException debería ser Exception.

Como las excepciones en tiempo de ejecución no tienen por qué ser especificadas en la clausula throws de un método, muchos desarrolladores de paquetes se preguntan: "¿No es más sencillo hacer que todas mis excepciones sean heredadas de Runtime Exception?" La respuesta a esta pregunta con más detalle en Excepciones en Tiempo de Ejecución -- La Controversia. La línea inferior dice que no deberías utilizar subclases de RuntimeException en tus clases a menos que tus excepciones sean realmente en tiempo de ejecución! Para la mayoría de nosotros, esto significa "NO, tus excepciones no deben descender de la clase RuntimeException."

Convenciones de Nombres

Es una buena práctica añadir la palabra "Exception" al final del nombre de todas las clases heredadas (directa o indirectamente) de la clase Exception. De forma similar, los nombres de las clases que se hereden desde la clase Error deberían terminar con la palabra "Error".


Ozito