
En un bloque try se ejecutan sentencias de todo tipo, llamadas a métodos, creación de objetos. . .; en ciertas aplicaciones se pedirán recursos al sistema para ser utilizados. Las aplicaciones que procesan información abren ficheros para leerlos, ficheros que se asignarán con uso exclusivo.
Es obvio que todos estos recursos a los que se ha hecho mención tienen que ser liberados cuando el bloque try en que se han asignado termina; de igual forma, si no se ejecutan normalmente todas las sentencias del bloque porque ha habido alguna excepción, el catch que la captura debe preocuparse de liberar los recursos.
Java proporciona la posibilidad de definir un bloque de sentencias que se ejecutarán siempre, ya sea que termine el bloque try normalmente, o se produzca una excepción. La cláusula finally define un bloque de sentencias con esas características.
La cláusula finally es opcional, si está presente debe situarse después del último catch del bloque try. Incluso se permite que un bloque try no tenga catch asociados si tiene el bloque definido por la cláusula finally. El esquema siguiente indica cómo se especifica un bloque try-catch-finally:
try{
// sentencias
// acceso a archivos (uso exclusivo. . .)
// peticiones de recursos
}
catch(Exception1 e1){. . .}
catch(Exception2 e2){. . .}
finally{
// sentencias
// desbloqueo de archivos
// liberación de recursos
}
Ejemplo
Se declara la excepción RangoException que será lanzada en el caso de que un valor entero esté comprendido en un intervalo determinado. El bloque try-catch-finally se ejecuta; termine de una forma u otra siempre se ejecutan las sentencias del bloque que define finally, lo que se pone de manifiesto con una salida por pantalla.
public class RangoException extends Exception {
public RangoException(String mensaje) {
super(mensaje);
}
}
public class ConFinally {
static void meteo() throws RangoException{
for(int i=1;i<9;i++){
int r;
r = (int)(Math.random()*77);
if(r<3 || r>71)
throw new RangoException(«con el valor»+» «+ r);
}
System.out.println(«fin método meteo»);
}
static void gerea1(){
for(int h=1;h<9;h++)
try{
meteo();
}
catch(RangoException r){
System.out.println(«Excepción:»+ r +» «+»capturada»);
System.out.println(«Iteración: » + h);
break;
}
finally{
System.out.println(«Bloque final de try en gerea1()»);
}
}
public static void main(String[] args) {
try{
System.out.println(«Ejecuta main»);
gerea1();
}
finally{
System.out.println(«Bloque final de try en main()»);
}
System.out.println(«Termina el programa»);
}
}
La ejecución de este programa da lugar a esta salida:
Ejecuta main
Excepción:confinally.RangoException: con el valor 76 capturada
Iteración: 1
Bloque final de try en gerea1()
Bloque final de try en main()
Termina el programa
Se observa que al generarse el número aleatorio 76, el método meteo() lanza la excepción RangoException. Esta es captada por el catch que tiene el argumento RangoException, ejecuta las sentencias definidas en su bloque y se sale del bucle. A continuación, se ejecutan las sentencias del bloque finally y devuelve control al método main(); acaba el bloque try de este y de nuevo se ejecuta el bloque finally correspondiente.