Está en la página 1de 9

Unidad 5 Exepciones

5.1 Definicin de excepciones




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


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.

5.2 Tipos de excepciones

Existen varios tipos fundamentales de excepciones:
Error: Excepciones que indican problemas muy graves, que suelen ser no
recuperables y no deben casi nunca ser capturadas.
Exception: Excepciones no definitivas, pero que se detectan fuera del tiempo
de ejecucin.
RuntimeException: Excepciones que se dan durante la ejecucin del
programa.







Todas las excepciones tienen como clase base la clase Throwable, que
est incluida en el paquete java.lang, y sus mtodos son:

Trowable( String mensaje ); Constructor. La cadena es opcional
Throwable fillInStackTrace(); Llena la pila de traza de ejecucin.
String getLocalizedMessage(); Crea una descripcin local de este
objeto.
String getMessage(); Devuelve la cadena de error del objeto.
Void printStackTrace( PrintStream_o_PrintWriter s ); Imprime
este objeto y su traza en el flujo del parmetro s, o en la salida estndar
(por defecto).
String toString; Devuelve una breve descripcin del objeto.


5.3 Propagacin de excepciones

La clusula catch comprueba los argumentos en el mismo orden en que
aparezcan en el programa. Si hay alguno que coincida, se ejecuta el bloque y
sigue el flujo de control por el bloque finally (si lo hay) y concluye el control de
la excepcin.

Si ninguna de las clusulas catch coincide con la excepcin que se ha
producido, entonces se ejecutar el cdigo de la clusula finally (en caso de
que la haya). Lo que ocurre en este caso, es exactamente lo mismo que si la
sentencia que lanza la excepcin no se encontrase encerrada en el bloque try.
El flujo de control abandona este mtodo y retorna prematuramente al mtodo
que lo llam. Si la llamada estaba dentro del mbito de una sentencia try,
entonces se vuelve a intentar el control de la excepcin, y as continuamente.

Cuando una excepcin no es tratada en la rutina en donde se produce, lo que
sucede es lo siguiente. El sistema Java busca un bloque try..catch ms all de
la llamada, pero dentro del mtodo que lo trajo aqu. Si la excepcin se
propaga de todas formas hasta lo alto de la pila de llamadas sin encontrar un
controlador especfico para la excepcin, entonces la ejecucin se detendr
dando un mensaje. Es decir, podemos suponer que Java nos est
proporcionando un bloque catch por defecto, que imprime un mensaje de
error, indica las ltimas entradas en la pila de llamadas y sale.

No hay ninguna sobrecarga en el sistema por incorporar sentencias try al
cdigo. La sobrecarga se produce cuando se genera la excepcin.

Se ha indicado ya que un mtodo debe capturar las excepciones que genera, o
en todo caso, declararlas como parte de su llamada, indicando a todo el mundo
que es capaz de generar excepciones. Esto debe ser as para que cualquiera
que escriba una llamada a ese mtodo est avisado de que le puede llegar una
excepcin, en lugar del valor de retorno normal. Esto permite al programador
que llama a ese mtodo, elegir entre controlar la excepcin o propagarla hacia
arriba en la pila de llamadas. La siguiente lnea de cdigo muestra la forma
general en que un mtodo declara excepciones que se pueden propagar fuera
de l, tal como se ha visto a la hora de tratar la sentencia throws:

tipo_de_retorno( parametros ) throws e1,e2,e3 { }
Los nombres e1,e2,... deben ser nombres de excepciones, es decir, cualquier
tipo que sea asignable al tipo predefinido Throwable. Observar que, como en la
llamada al mtodo se especifica el tipo de retorno, se est especificando el tipo
de excepcin que puede generar (en lugar de un objeto Exception).

He aqu un ejemplo, tomado del sistema Java de entrada/salida:

byte readByte() throws IOException; short readShort() throws IOException;
char readChar() throws IOException; void writeByte( int v ) throws
IOException; void writeShort( int v ) throws IOException; void writeChar( int v
) throws IOException;
Lo ms interesante aqu es que la rutina que lee un char, puede devolver un
char; no el entero que se requiere en C. C necesita que se devuelva un int,
para poder pasar cualquier valor a un char, y adems un valor extra (-1) para
indicar que se ha alcanzado el final del fichero. Algunas de las rutinas Java
lanzan una excepcin cuando se alcanza el fin del fichero.

Cuando se crea una nueva excepcin, derivando de una clase Exception ya
existente, se puede cambiar el mensaje que lleva asociado. La cadena de texto
puede ser recuperada a travs de un mtodo.

Normalmente, el texto del mensaje proporcionar informacin para resolver el
problema o sugerir una accin alternativa. Por ejemplo:

class SinGasolina extends Exception { SinGasolina( String s ) { // constructor
super( s ); } .... // Cuando se use, aparecer algo como esto try { if( j < 1 )
throw new SinGasolina( "Usando deposito de reserva" ); } catch( SinGasolina e
) { System.out.println( o.getMessage() ); }

Esto, en tiempo de ejecucin originara la siguiente salida por pantalla:

> Usando deposito de reserva
Otro mtodo que es heredado de la
superclase Throwable es printStackTrace(). Invocando a este mtodo sobre
una excepcin se volcar a pantalla todas las llamadas hasta el momento en
donde se gener la excepcin (no donde se maneje la excepcin). Por ejemplo:

// Capturando una excepcin en un mtodo class testcap { static int slice0[] =
{ 0,1,2,3,4 }; public static void main( String a[] ) { try { uno(); } catch(
Exception e ) { System.out.println( "Captura de la excepcion en main()" );
e.printStackTrace(); } } static void uno() { try { slice0[-1] = 4; } catch(
NullPointerException e ) { System.out.println( "Captura una excepcion
diferente" ); } } }

Cuando se ejecute ese cdigo, en pantalla observaremos la siguiente salida:

> Captura de la excepcion en main() >
java.lang.ArrayIndexOutOfBoundsException: -1 at testcap.uno(test5p.java:19)
at testcap.main(test5p.java:9)

Con todo el manejo de excepciones podemos concluir que se proporciona un
mtodo ms seguro para el control de errores, adems de representar una
excelente herramienta para organizar en sitios concretos todo el manejo de los
errores y, adems, que se pueden proporcionar mensajes de error ms
decentes al usuario indicando qu es lo que ha fallado y por qu, e incluso
podemos, a veces, recuperar al programa automticamente de los errores.

La degradacin que se produce en la ejecucin de programas con manejo de
excepciones est ampliamente compensada por las ventajas que representa en
cuanto a seguridad de funcionamiento de esos mismos programas.
5.4 Gestin de excepciones

Las excepciones son el mecanismo por el cual pueden controlarse en un
programa Java las condiciones de error que se producen. Estas
condiciones de error pueden ser errores en la lgica del programa como
un ndice de un array fuera de su rango, una divisin por cero o errores
disparados por los propios objetos que denuncian algn tipo de estado
no previsto, o condicin que no pueden manejar.

La idea general es que cuando un objeto encuentra una condicin que
no sabe manejar crea y dispara una excepcin que deber ser capturada
por el que le llam o por alguien ms arriba en la pila de llamadas. Las
excepciones son objetos que contienen informacin del error que se ha
producido y que heredan de la clase Throwable o de la clase Exception.
Si nadie captura la excepcin interviene un manejador por defecto que
normalmente imprime informacin que ayuda a encontrar quin produjo
la excepcin.
Existen dos categoras de excepciones:
Excepciones verificadas: El compilador obliga a verificarlas. Son todas
las que son lanzadas explicitamente por objetos de usuario.
Excepciones no verificadas: El compilador no obliga a su verificacin.
Son excepciones como divisiones por cero, excepciones de puntero nulo,
o ndices fuera de rango.
Generacion de exepciones

Supongamos que tenemos una clase Empresa que tiene un array de
objetos Empleado (clase vista en captulos anteriores). En esta clase
podramos tener mtodos para contratar un Empleado (aadir un nuevo
objeto al array), despedirlo (quilarlo del array) u obtener el nombre a
partir del nmero de empleado. La clase podra ser algo as como lo
siguiente:

public class Empresa {
String nombre;
Empleado [] listaEmpleados;
int totalEmpleados = 0;
. . .
Empresa(String n, int maxEmp) {
nombre = n;
listaEmpleados = new Empleado [maxEmp];
}
. . .
void nuevoEmpleado(String nombre, int sueldo) {
if (totalEmpleados < listaEmpleados.length ) {
listaEmpleados[totalEmpleados++]
= new Empleado(nombre,sueldo);
}
}
}
Observese en el mtodo nuevoEmpleado que se comprueba que hay
sitio en el array para almacenar la referencia al nuevo empleado. Si lo
hay se crea el objeto. Pero si no lo hay el mtodo no hace nada ms. No
da ninguna indicacin de si la operacin ha tenido xito o no. Se podra
hacer una modificacin para que, por ejemplo el mtodo devolviera un
valor booleano true si la operacin se ha completado con xito y false si
ha habido algn problema.

Otra posibilidad es generar una excepcin verificada (Una excepcin no
verificada se producira si no se comprobara si el nuevo empleado va a
caber o no en el array). Vamos a ver como se hara esto.

Las excepciones son clases, que heredan de la clase genrica Exception.
Es necesario por tanto asignar un nombre a nuestra excepcin. Se
suelen asignar nombres que den alguna idea del tipo de error que
controlan. En nuestro ejemplo le vamos a llamar
CapacidadEmpresaExcedida.
Para que un mtodo lance una excepcin:
Debe declarar el tipo de excepcin que lanza con la clusula throws, en
su declaracin.
Debe lanzar la excepcin, en el punto del cdigo adecuado con la
sentencia throw.
En nuestro ejemplo:

void nuevoEmpleado(String
nombre, int sueldo) throws CapacidadEmpresaExcedida {
if (totalEmpleados < listaEmpleados.length) {
listaEmpleados[totalEmpleados++]
= new Empleado(nombre,sueldo);
}
else throw new CapacidadEmpresaExcedida(nombre);
}





Adems, necesitamos escribir la clase CapacidadEmpresaExcedida. Sera
algo as:
public class CapacidadEmpresaExcedida extends Exception {
CapacidadEmpresaExcedida(String nombre) {
super("No es posible aadir el empleado " + nombre);
}
. . .
}
La sentencia throw crea un objeto de la clase
CapacidadEmpresaExcedida . El constructor tiene un argumento (el
nombre del empleado). El constructor simplemente llama al constructor
de la superclase pasndole como argumento un texto explicativo del
error ( y el nombre del empleado que no se ha podido aadir).

La clase de la excepcin puede declarar otros mtodos o guardar datos
de depuracin que se consideren oportunos. El nico requisito es que
extienda la clase Exception. Consultar la documentacin del API para ver
una descripcin completa de la clase Exception.

De esta forma se pueden construir mtodos que generen excepciones.

5.5 Creacin y manejo de excepciones creadas por el usuario

Las excepciones predefinidas cubren las situaciones de error ms habituales
con las que nos podemos encontrar, relacionadas con el propio lenguaje y
el hardware. Cuando se desarrollan aplicaciones existen otras situaciones de
error de ms alto nivel relacionadas con la funcionalidad de nuestros
programas.

Imaginemos una aplicacin informtica que controla la utilizacin de los
remontes de una estacin de esqu: los pases de acceso a los remontes son
personales e intransferibles y dispondrn de un cdigo de barras que los
identifica. Cada vez que un usuario va a hacer uso de un remonte debe
introducir su pase de acceso en una mquina de validacin, que a cciona un
torno y devuelve el pase. El sistema puede constar de un ordenador central al
que le llegan telemticamente los datos correspondientes a los cdigos de
barras de los pases que en cada momento se estn introduciendo en cada
mquina de validacin d e cada remonte; si un cdigo de barras est en regla,
el ordenador enva una orden de liberar el torno para permitir al usuario
acceder al remonte. El ordenador central habitualmente recibir cdigos
correctos utilizados en momentos adecuados, sin embargo, en ciertas
ocasiones nos encontraremos con situaciones anmalas:

1 Cdigo de barras ilegible

2 Cdigo de barras no vlido (por ejemplo correspondiente a un pase
caducado)

3 Cdigo de barras utilizado en otro remonte en un periodo de tiempo
demasiado breve

Antes de nada tenemos que tener en cuenta que el mecanismo de excepciones es
muy lento en ejecucin comparado con la utilizacin de instrucciones
condicionales. Aunque el mecanismo de excepciones es elegante, debemos
utilizarlo con prudencia: nicamente en situaciones que realmente son
excepcionales.

Definicin de una excepcin definida por el programador

En programacin orientada a objetos lo ms adecuado es que las excepciones
sean objetos, por lo que en Java definiremos las excepciones como clases.
Nuestras clases de excepcin, en general, heredarn de la clase Exception.

En las clases que nos creemos a partir de Exception, incluiremos al menos el
constructor vaco y otro que contenga un String como argumento. Este String
se inicializa automticamente con el nombre de la clase; la inicializacin se
realiza en la superclase Throwable. El texto que pongamos al hacer uso del
segundo constructor se aadir al nombre de la clase insertado por la
superclase.

A continuacin se presenta una clase (ExPropia) muy simple que define una
excepcin propia:

1 public class ExPropia extends Exception {
2
3 ExPropia () {
4 super("Esta es mi propia excepcion");
5 }
6
7 ExPropia (String s) {
8 super(s);
9 }
10
11 }

En la lnea 1 se define nuestra clase Expropia que hereda de Exception. La
lnea 3 define el constructor vaco, que en este caso aade el texto Esta es mi
propia excepcion al nombre de la clase, quedando ExPropia: Esta es mi
propia excepcion. La lnea 7 define el constructor con un String como
argumento; nos servir para aadir el texto que deseemos al instanciar la
clase.

También podría gustarte