You are on page 1of 10

24/4/2014

ENI Training - Libro online

Gestin de las excepciones


La vida de un desarrollador no es del todo rosa! Los errores son una de las fuentes principales de estrs. De hecho, si nos fijamos bien, podemos clasificar estos errores que nos arruinan la vida en tres categoras. Veremos cada una de ellas as como las soluciones existentes para resolverlos.

1. Los errores de sintaxis


Este error se produce en el momento de la compilacin cuando una palabra clave del lenguaje est mal ortografiada. Muy frecuentes con las herramientas de desarrollo en las cuales el editor de cdigo y el compilador son dos entidades separadas, se hacen raras en los entornos de desarrollo integrado (Eclipse, NetBeans, Jbuilder). La mayora de estos entornos proponen un anlisis sintctico al mismo tiempo que se introduce el cdigo. Los ejemplos siguientes se han obtenido a partir del entorno Eclipse. Si se detecta un error de sintaxis, entonces el entorno propone soluciones posibles para corregir este error.

Adems, las "faltas de ortografa" en los nombres de campos o mtodos, se eliminan fcilmente mediante las funcionalidades disponibles en estos entornos.

2. Los errores de ejecucin


Estos errores aparecen despus de la compilacin cuando lanzamos la ejecucin de la aplicacin. La
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 1/10

24/4/2014

ENI Training - Libro online

sintaxis del cdigo es correcta, pero el entorno de la aplicacin no permite la ejecucin de una instruccin empleada en la aplicacin. Por ejemplo es el caso, si intenta abrir un fichero que no existe en el disco de su mquina. Sin duda, obtendr un mensaje de este tipo.

No es un mensaje muy simptico para el usuario! Afortunadamente, Java permite la recuperacin de este tipo de error y evita as la visualizacin de este mensaje preocupante. Vamos a detallar esto ms adelante en este captulo.

3. Les errores de lgica


Los peores enemigos de los desarrolladores. Todo se compila sin problema, todo se ejecuta sin errores, y sin embargo "no funciona como estaba previsto!!!" En este caso, hay que retomar la lgica de funcionamiento de la aplicacin. Las herramientas de depuracin nos permiten seguir el desarrollo de la aplicacin, situar puntos de interrupcin, visualizar el contenido de las variables, etc. Estas herramientas no sustituyen sin embargo una buena dosis de reflexin (y a veces algunas pastillas de aspirina).

a. Las excepciones
Cuando se produce un error durante la ejecucin de un mtodo, se crea un objeto E x c e p t i o n para representar el error que acaba de producirse. Este objeto contiene numerosa informacin relativa al error ocurrido en la aplicacin as como el estado de la aplicacin en el momento de la aparicin del error. Luego se transmite este objeto a la mquina virtual. Esto activa la excepcin. Entonces, la mquina virtual debe buscar una solucin para resolverla. Para ello, explora los diferentes mtodos llamados para alcanzar la ubicacin donde se produjo el error. En estos distintos mtodos, la mquina busca un gestor de excepciones capaz de tratar el problema. La bsqueda empieza con el mtodo en el cual se activ el error, y luego, sube hasta el mtodo main de la aplicacin, si es necesario. Cuando se localiza un gestor de excepcin adecuado, se le transmite el objeto E x c e p t i o n para que se encargue de su tratamiento. Si la bsqueda no da resultado, la aplicacin se detiene. Las excepciones se suelen distinguir entre tres categoras. Las excepciones verificadas corresponden a una situacin anormal durante el
2/10

http://www.eni-training.com/client_net/mediabook.aspx?idR=65884

24/4/2014

ENI Training - Libro online

funcionamiento de la aplicacin. Esta situacin suele ir relacionada a un elemento exterior a la aplicacin, como por ejemplo una conexin hacia una base de datos o una lectura de fichero. Los errores corresponden a condiciones excepcionales exteriores a la aplicacin que esta ltima no puede prever. Los errores relacionados con una utilizacin incorrecta de una funcionalidad del lenguaje, o un error de lgica en el diseo de la aplicacin. El error ms frecuente que podr encontrar en sus principios con Java ser sin duda la excepcin N u l l P o i n t e r E x c e p t i o n activada durante la utilizacin de una variable no inicializada. nicamente las excepciones verificadas deben ser tratadas obligatoriamente en el momento de su activacin o propagadas al cdigo llamador.

b. Recuperacin de excepciones
La gestin de las excepciones ofrece la posibilidad de proteger un bloque de cdigo contra las excepciones que podran introducirse en l. El cdigo "peligroso" debe ser ubicado en un bloque t r y . Si una excepcin se activa en este bloque de cdigo, el o los bloques de cdigo c a t c h son examinados. Si uno es capaz de tratar la excepcin, se ejecuta el cdigo correspondiente, si no, la misma excepcin se activa para eventualmente ser recuperada por un bloque t r yde mayor nivel. Una instruccin f i n a l l y permite marcar un grupo de instrucciones que sern ejecutadas ya sea a la salida del bloque t r y si no se produjo ninguna excepcin, o a la salida de un bloque c a t c h si se activ una excepcin. Por lo tanto, la sintaxis general es la siguiente:

t r y { . . . I n s t r u c c i o n e sp e l i g r o s a s . . . } c a t c h( e x c e p c i n 1e 1 ) { . . . c d i g oe j e c u t a d os is ep r o d u c eu n ae x c e p c i nd et i p oE x c e p c i n 1 . . . } c a t c h( e x c e p c i n 2e 2 ) { . . . c d i g oe j e c u t a d os is ep r o d u c eu n ae x c e p c i nd et i p oE x c e p c i n 2 . . . } f i n a l l y { . . . c d i g oe j e c u t a d oe nt o d oc a s oa n t e sd el as a l i d ad e lb l o q u et r yo d eu nb l o q u ec a t c h . . . } Esta estructura tiene un funcionamiento muy similar al s w i t c hc a s eya estudiado. Es necesario indicar para cada bloque c a t c hel tipo de excepcin que ste debe gestionar.

p u b l i cv o i dl e e r F i c h e r o ( S t r i n gn o m b r e )
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 3/10

24/4/2014

ENI Training - Libro online

{ F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( " c : \ \ D a t o s \ \ b a l a n c e . t x t " ) ; } c a t c h( F i l e N o t F o u n d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } b r = n e wB u f f e r e d R e a d e r ( n e wI n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; t r y { l n e a = b r . r e a d L i n e ( ) ; } c a t c h( I O E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; t r y { l n e a = b r . r e a d L i n e ( ) ; } c a t c h( I O E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } } En el ejemplo anterior, cada instruccin susceptible de activar una excepcin est protegida por su propio bloque t r y . Esta solucin presenta la ventaja de ser extremadamente precisa para la gestin de las excepciones en detrimento de la legibilidad del cdigo. Una solucin ms sencilla consiste en agrupar varias instrucciones en un mismo bloque t r y . Se puede codificar tambin nuestro ejemplo de la manera siguiente:

p u b l i cv o i dl e e r F i c h e r o ( S t r i n gn o m b r e ) { F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( n o m b r e ) ; b r = n e wB u f f e r e d R e a d e r ( n e wI n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; l n e a = b r . r e a d L i n e ( ) ; w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; l n e a = b r . r e a d L i n e ( ) ; } } c a t c h( F i l e N o t F o u n d E x c e p t i o ne ) {
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 4/10

24/4/2014

ENI Training - Libro online

e . p r i n t S t a c k T r a c e ( ) ; } c a t c h( I O E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } } El cdigo es ms legible, pero a cambio perdemos precisin ya que se vuelve difcil determinar qu instruccin activ la excepcin. Tambin hay que tener cuidado con el orden de los bloques c a t c hy organizarlos siempre desde el ms preciso hasta el ms general. Las excepciones, al ser clases, pueden tener relaciones de herencia. Si se preve un bloque c a t c h para gestionar un tipo particular de excepcin, ste puede tambin gestionar todos los tipos de excepciones que heredan de ella. Es el caso en nuestro ejemplo ya que la clase F i l e N o t F o u n d E x c e p t i o nhereda de la clase I O E x c e p t i o n . El compilador detecta tal situacin y genera un error. Si modificamos nuestro cdigo de la manera siguiente:

p u b l i cv o i dl e e r F i c h e r o ( S t r i n gn o m b r e ) { F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( n o m b r e ) ; b r = n e wB u f f e r e d R e a d e r ( n e wI n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; l n e a = b r . r e a d L i n e ( ) ; w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; l n e a = b r . r e a d L i n e ( ) ; } } c a t c h( I O E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } c a t c h( F i l e N o t F o u n d E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; }

} Obtenemos este error en el momento de la compilacin.

http://www.eni-training.com/client_net/mediabook.aspx?idR=65884

5/10

24/4/2014

ENI Training - Libro online

El cdigo puede ser todava ms preciso si se indica que un mismo bloque c a t c h debe gestionar varios tipos de excepciones. Los distintos tipos de excepciones que puede procesar un bloque c a t c hdeben indicarse en la declaracin separndolas mediante el carcter |.

p u b l i cv o i dl e e r F i c h e r o ( S t r i n gn o m b r e ) { F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; d o u b l es u m a = 0 ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( n o m b r e ) ; b r = n e wB u f f e r e d R e a d e r ( n e w I n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; l n e a = b r . r e a d L i n e ( ) ; w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; l n e a = b r . r e a d L i n e ( ) ; s u m a = s u m a + D o u b l e . p a r s e D o u b l e ( l n e a ) ; } S y s t e m . o u t . p r i n t l n ( t o t a l : + s u m a ) ; } c a t c h( I O E x c e p t i o n|N u m b e r F o r m a t E x c e p t i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } }

c. Excepciones asociadas a recursos


Numerosas aplicaciones necesitan con frecuencia acceder a recursos externos. Los archivos y las bases de datos son sin duda los ejemplos ms comunes. El uso de estos recursos comienza por una operacin de apertura, sigue con la explotacin del recurso, y finaliza con el cierre del recurso. A menudo, los mtodos que permiten explotar estos recursos son susceptibles de provocar numerosas excepciones y de hecho se sitan en una estructura de tipo try-catch. Tambin puede verse aqu el cierre del recurso al final de la ejecucin de las instrucciones que contiene. Los recursos deben declararse e instanciarse entre parntesis tras la palabra clave t r y . Si el bloque t r ycontiene varias declaraciones, stas deben estar separadas por un punto y coma. Al finalizar la ejecucin del bloque t r y el mtodo c l o s e se invoca sobre cada recurso declarado a nivel de la palabra clave t r y . Esta llamada se realiza siempre antes de ejecutar un bloque c a t c ho del bloque f i n a l l y . Para asegurar que este mecanismo funciona, las clases correspondientes a los recursos utilizados deben implementar la interfaz C l o s e a b l eo A u t o C l o s e a b l e . Ambas interfaces
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 6/10

24/4/2014

ENI Training - Libro online

exigen la existencia del mtodo c l o s een la clase del recurso utilizado en el bloque t r y . En el ejemplo que aparece a continuacin el objeto B u f f e r e d R e a d e rse cierra automticamente tras la ejecucin del bloque t r y .

S t r i n gr e s p o n s e = ; t r y( B u f f e r e d R e a d e rb r = n e wB u f f e r e d R e a d e r ( n e w I n p u t S t r e a m R e a d e r ( S y s t e m . i n ) ) ) { w h i l e( ! r e s p u e s t a . e q u a l s ( f i n ) ) { . . . . . . r e s p o n s e = b r . r e a d L i n e ( ) ; } c a t c h ( I O E x c e p c i o ne ) { e . p r i n t S t a c k T r a c e ( ) ; } El cdigo de cada bloque c a t c hpuede obtener ms informacin sobre la excepcin que debe tratar utilizando los mtodos disponibles en la clase correspondiente a la excepcin. Los mtodos siguientes son los ms tiles para obtener informacin adicional sobre la excepcin.

g e t M e s s a g e : permite obtener el mensaje de error asociado a la excepcin. g e t C a u s e : permite obtener la excepcin inicial si se utiliza la traza de la excepcin. g e t S t a c k T r a c e : permite obtener una pila de S t a c k T r a c e E l e m e n t de la cual cada
elemento representa un mtodo llamado hasta el mtodo donde se trata la excepcin. Para cada uno de ellos, obtenemos la informacin siguiente: El nombre de la clase donde se encuentra el mtodo: g e t C l a s s N a m e El nombre del fichero donde se encuentra esta clase: g e t F i l e n a m e Le nmero de lnea donde se activ la excepcin: g e t L i n e N u m b e r El nombre del mtodo: g e t M e t h o d N a m e . Se puede utilizar esta informacin para generar ficheros histricos de funcionamiento de la aplicacin. Aqu tiene un ejemplo de grabacin de esta informacin en un fichero texto.

i m p o r tj a v a . i o . B u f f e r e d R e a d e r ; i m p o r tj a v a . i o . B u f f e r e d W r i t e r ; i m p o r tj a v a . i o . F i l e I n p u t S t r e a m ; i m p o r tj a v a . i o . F i l e N o t F o u n d E x c e p t i o n ; i m p o r tj a v a . i o . F i l e W r i t e r ; i m p o r tj a v a . i o . I O E x c e p t i o n ; i m p o r tj a v a . i o . I n p u t S t r e a m R e a d e r ; i m p o r tj a v a . u t i l . G r e g o r i a n C a l e n d a r ;

p u b l i cc l a s sL e c t u r a F i c h e r o { p u b l i cs t a t i cv o i dm a i n ( S t r i n ga r g s [ ] ) { t r y{ l e e r F i c h e r o ( " b a l a n c e . t x t " ) ; }
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 7/10

24/4/2014

ENI Training - Libro online

c a t c h( N o F u n c i o n a E x c e p c i o ne ) { F i l e W r i t e rl o g ; B u f f e r e d W r i t e rb r ; t r y { l o g = n e wF i l e W r i t e r ( " h i s t r i c o . t x t " , t r u e ) ; b r = n e wB u f f e r e d W r i t e r ( l o g ) ; b r . w r i t e ( " > " +n e wG r e g o r i a n C a l e n d a r ( ) . g e t T i m e ( ) + " < \ r \ n " ) ; b r . w r i t e ( " e r r o r :"+e . g e t M e s s a g e ( ) + " \ r \ n " ) ; f o r( i n ti = 0 ; i < e . g e t S t a c k T r a c e ( ) . l e n g t h ; i + + ) { b r . w r i t e ( " e ne lf i c h e r o " + e . g e t S t a c k T r a c e ( ) [ i ] . g e t F i l e N a m e ( ) ) ; b r . w r i t e ( "al al n e a" + e . g e t S t a c k T r a c e ( ) [ i ] . g e t L i n e N u m b e r ( ) ) ; b r . w r i t e ( "e n e lm t o d o" + e . g e t S t a c k T r a c e ( ) [ i ] . g e t M e t h o d N a m e ( ) ) ; b r . w r i t e ( "d el ac l a s e" +e . g e t S t a c k T r a c e ( ) [ i ] . g e t C l a s s N a m e ( ) +" \ r \ n " ) ; } b r . c l o s e ( ) ; l o g . c l o s e ( ) ; } c a t c h( I O E x c e p t i o ne x ) { S y s t e m . o u t . p r i n t l n ( " e r r o re nl aa p l i c a c i n " ) ; } } } p u b l i cs t a t i cv o i dl e e r F i c h e r o ( S t r i n gn o m b r e )t h r o w sN o F u n c i o n a E x c e p c i o n { F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( n o m b r e ) ; b r = n e wB u f f e r e d R e a d e r ( n e wI n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; l n e a = b r . r e a d L i n e ( ) ; w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; l n e a = b r . r e a d L i n e ( ) ; } } c a t c h( F i l e N o t F o u n d E x c e p t i o ne ) { t h r o wn e wN o F u n c i o n a E x c e p c i o n ( " e lf i c h e r on oe x i s t e " , e ) ; } c a t c h( I O E x c e p t i o ne ) { t h r o wn e wN o F u n c i o n a E x c e p c i o n ( " e r r o rd el e c t u r ad e l f i c h e r o " , e ) ; } } }
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 8/10

24/4/2014

ENI Training - Libro online

d. Creacin y activacin de excepciones


Las excepciones son, ante todo, clases, por lo tanto es posible crear nuestras propias excepciones al heredar de una de las numerosas clases de excepcin ya disponibles. Para respetar las convenciones, se aconseja terminar el nombre de la clase con el trmino Excepcion. Podemos escribir, por ejemplo, el cdigo siguiente:

p u b l i cc l a s sN o F u n c i o n a E x c e p c i o ne x t e n d sE x c e p t i o n { p u b l i cN o F u n c i o n a E x c e p c i o n ( ) { s u p e r ( ) ; } p u b l i cN o F u n c i o n a E x c e p c i o n ( S t r i n gm e s s a g e ) { s u p e r ( m e s s a g e ) ; } p u b l i cN o F u n c i o n a E x c e p c i o n ( S t r i n gm e s s a g e ,T h r o w a b l ec a u s e ) { s u p e r ( m e s s a g e , c a u s e ) ; } p u b l i cN o F u n c i o n a E x c e p c i o n ( T h r o w a b l ec a u s e ) { s u p e r ( c a u s e ) ; } } Se desaconseja encarecidamente la sobrecarga de los constructores de la clase base para conservar la coherencia entre les clases de excepcin.

Esta clase puede ser utilizada luego para lanzar una excepcin personalizada. Para activar una excepcin, hay que crear previamente una instancia de la clase correspondiente y luego activar la excepcin con la palabra clave t h r o w . La activacin de una excepcin en una funcin con la palabra clave t h r o wprovoca la salida inmediata de la funcin. El cdigo siguiente activa una excepcin personalizada en los bloques c a t c h .

p u b l i cs t a t i cv o i dl e e r F i c h e r o 2 ( S t r i n gn o m b r e )t h r o w sN o F u n c i o n a E x c e p c i o n { F i l e I n p u t S t r e a mf i c h e r o = n u l l ; B u f f e r e d R e a d e rb r = n u l l ; S t r i n gl n e a = n u l l ; t r y { f i c h e r o = n e wF i l e I n p u t S t r e a m ( n o m b r e ) ; b r = n e wB u f f e r e d R e a d e r ( n e wI n p u t S t r e a m R e a d e r ( f i c h e r o ) ) ; l n e a = b r . r e a d L i n e ( ) ; w h i l e( l n e a ! = n u l l ) { S y s t e m . o u t . p r i n t l n ( l n e a ) ; l n e a = b r . r e a d L i n e ( ) ; } } c a t c h( F i l e N o t F o u n d E x c e p t i o ne ) { t h r o wn e wN o F u n c i o n a E x c e p c i o n ( " e lf i c h e r on oe x i s t e " , e ) ; }
http://www.eni-training.com/client_net/mediabook.aspx?idR=65884 9/10

24/4/2014

ENI Training - Libro online

c a t c h( I O E x c e p t i o ne ) { t h r o wn e wN o F u n c i o n a E x c e p c i o n ( " e r r o rd el e c t u r ad e lf i c h e r o " , e ) ; } } Cuando una funcin es susceptible de activar una excepcin, debemos sealarlo en la firma de esta funcin con la palabra clave t h r o w sseguida de la lista de las excepciones que puede activar. Cuando, ms tarde, se use esta funcin en otra, tendr que tener en cuenta obligatoriamente esta o estas posibles excepciones. Tendr que gestionar la excepcin con un bloque t r y. . .c a t c ho propagarla aadiendo la palabra clave t h r o w sa la declaracin de la funcin. Sin embargo hay que ser prudente y no propagar las excepciones ms all del mtodo m a i nya que en este caso, es la mquina virtual Java quien las recupera y detiene la aplicacin de forma brusca.

http://www.eni-training.com/client_net/mediabook.aspx?idR=65884

10/10

You might also like