Componente
sintáctico de sentencias “try”.
El bloque finally
se ejecuta siempre al acabar el bloque try, tanto si acaba bien como si acaba
mal, sea cual sea el significado de acabar bien o mal.
El ejemplo
siguiente muestra como el bloque puede acabar bien (calculando la raíz cuadrada
de un real positivo) o mal (por diferentes motivos de formato o números
negativos); pero siempre incrementa el número de pruebas realizadas:
Inversos.java |
public
class Inversos { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int pruebas = 0; while (true) { double inverso = 0; try { String x = scanner.next(); if (x.equals("fin")) break; int valor = Integer.parseInt(x); inverso= 100 / valor; } catch (Exception e) { System.out.println(" -> " + e); inverso = 0; } finally { pruebas++; System.out.println(" -> " + pruebas + ": " + inverso); } } } } |
ejecución |
$
java Inversos 2 -> 1: 50.0 dos -> java.lang.NumberFormatException: For
input string: "dos" -> 2: 0.0 0 -> java.lang.ArithmeticException: / by
zero -> 3: 0.0 fin -> 4: 0.0 |
El bloque finally
puede emplearse incluso sin bloques catch, aprovechando su
característica de que siempre se ejecuta al salir del bloque try.
El siguiente
ejemplo muestra como medir el tiempo que tarda un algoritmo independientemente
de que termine bien o mal:
Concretamente, en el ejemplo se busca un cero de una función en un
intervalo dado. Como algoritmo se usa el consistente en ir dividiendo el
intervalo en mitades hasta acotarlo. Hay varias razones por las que puede no
funcionar: la función no está definida en algún punto, o presenta una
discontinuidad, o simplemente no pasa por cero. Todas estas causas se traducen
en el lanzamiento de una excepción informativa.
Funcion.java |
public
class Funcion { private static final double ERROR =
1E-12; public double y(double x) { return Math.tan(x); // discontinuidad en x= PI/2 } public double cero(double a, double z) throws Exception { if (a > z) throw new
Exception("a > z"); double fa = y(a); double fz = y(z); if (Math.abs(fa) < ERROR) return
a; if (Math.abs(fz) < ERROR) return
z; if (fa * fz > 0) throw new Exception("no pasa por cero en el intervalo"); double m = (a + z) / 2; double fm = y(m); if (Math.abs(fm) < ERROR) return
m; if (Math.abs(a - z) < ERROR) throw new Exception("función discontinua"); if (fa * fm < 0) return cero(a, m); else return cero(m, z); } public static void main(String[] args) throws Exception { // nadie captura la excepción long t0 =
System.currentTimeMillis(); try { Funcion f = new Test(); System.out.println("raíz=
" + f.cero(1, 3)); } finally { long t2 =
System.currentTimeMillis(); System.out.println((t2 - t0) +
"ms"); } } } |
Temas relacionados
Vademécum
¿Qué hace finally con una excepción lanzada y no capturada dentro del try?
¿Puede hacerse "return" desde dentro del finally?
¿Puede lanzarse una excepción desde dentro del finally?