domingo, 26 de febrero de 2012

5.3 Propagación de excepciones

Para descargar el documento de este tema, haz clic aquí

Las instrucciones que tenemos dentro de un bloque  try a menudo contienen llamadas a métodos que a su vez pueden realizar llamadas a otros métodos y así sucesivamente. Cualquiera de los métodos llamados puede provocar una excepción y cualquiera de los métodos puede, o no, tratarla (con bloques catch). Ó
Una excepción no tratada en un bloque se propaga hacia el bloque llamante. Este mecanismo de propagación continúa mientras no se trate la excepción o se llegue al método de nivel superior. Si la excepción no se trata en el método de nivel superior, se imprime un mensaje de error por consola.
En el gráfico anterior se presenta el caso de un bloque  try que contiene una llamada a un método Metodo_A que a su vez hace una llamada a Metodo_B, donde se produce una excepción. Como la excepción no es tratada en Metodo_B se propaga al bloque llamante (Metodo_A); a su vez la excepción no es tratada en Metodo_A, por lo que se propaga al bloque try, donde sí que es capturada por un catch.
En el caso de que un método capture y trate la excepción, el mecanismo de propagación se termina y la ejecución de los métodos llamados y el bloque  try del método llamante continúan como si la excepción no se hubiera producido: 
 
En muchas ocasiones, después de tratar la excepción a un nivel, resulta conveniente que también sea tratada a niveles superiores; por ejemplo, si estando leyendo de un fichero origen y escribiendo su contenido en un fichero destino nos encontramos con un error de lectura, además de tratar la excepción a ese nivel (cerrar los ficheros, etc.) sería deseable propagar la excepción al programa llamante para que informe al usuario y le permita hacer un nuevo intento si lo desea.
Para propagar de forma explícita una excepción se emplea la palabra reservada throw seguida del objeto excepción. Ejemplo: 
 try {
 // codigo
Origen.CopiaFichero(Destino);
// codigo
}
catch (IOException e) {
    System.out.println (“Error de lectura ¿Desea intentarlo de Nuevo?”);
    ..........
}

public void CopiaFichero (TipoFichero Destino) {
try {
   // codigo
}
catch (IOException e) {
    // cerrar ficheros, etc.
  throw e;
}

En el ejemplo anterior, el método  CopiaFichero, después de tratar la excepción, la propaga  (throw) al método llamante, que a su vez hace otro tratamiento de la excepción.

Estado de una excepción

Como hemos visto, todas las excepciones derivan de la clase  Throwable  y tienen acceso a sus dos constructores y sus 7 métodos. El estado de las instancias de esta clase se compone de un String que sirve de mensaje indicando las características de la excepción y una pila de ejecución que contiene la relación de métodos que se encuentran en ejecución en el momento en el que se produce la excepción. Los métodos más significativos de la clase Throwable son: 
 



Para ilustrar la forma de uso de estos métodos, en la clase  Excepcion2 modificamos el contenido de los bloques catch para imprimir la pila de ejecución: 
16        catch (ArithmeticException e) {
17           System.out.println("Division por cero");
18           e.printStackTrace();
19        }
20       
21        catch(IndexOutOfBoundsException e) {
22           System.out.println("Indice fuera del array");
23           e.printStackTrace();
24        }

A la nueva clase la hemos llamado  Excepcion3. La instrucción donde se realiza la división se encuentra en la línea 12 del método  main, mientras que la instrucción donde se asigna el valor a la posición concreta del array se encuentra en la línea 13 del método  main. A continuación se muestra el resultado de una posible ejecución del programa:



Como se puede observar, cada instrucción  e.printStackTrace() provoca la impresión de un breve mensaje acerca de la excepción, seguido de la pila de ejecución de los métodos del programa (en este caso sólo el método  main) con indicación de la línea de cada método donde se ha producido la excepción.

No hay comentarios:

Publicar un comentario