Hay una gran diferencia en los dos fragmentos que ha presentado, p. Ej. cuando el bloque catch
arroja una excepción, el bloque finally
todavía se ejecutará por su semántica.
Ese es el siguiente fragmento de código imprime "Finally!"
, pero no "What about me???"
:
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
En términos generales, la finally
de un bloque try
prácticamente siempre es ejecutado. No hay tal garantía para ningún código que siga el bloque try
.
Pero ¿y si mi bloque catch
es sólo un simple print
declaración?
Todavía hay ninguna garantía de que no lo hará throw
algo. Algo podría salir mal, por ejemplo la construcción del mensaje detallado de excepción.
Incluso si hace un mejor esfuerzo, garantiza que el código catch
es "seguro" y siempre se ejecutará el código que sigue a la declaración try
, entonces la pregunta es "¿Por qué?". ¿Por qué evitar finally
pero luego intentas tanto para replicar su semántica?
finally
semántica está garantizada, no requiere ninguna carga de la prueba del escritor o el lector del código. Precisamente debido a esto, es idiomático para usar el bloque finally
para poner el código obligatorio de "limpieza". El uso de finally
garantiza la corrección y mejora la capacidad de escritura y la legibilidad.
Tenga en cuenta que rara vez es útil disponer de un 'try' comunicado tanto con un' catch' y una 'finalmente' si no quieres código desordenado. –
@Tom ¿por qué es eso? sirven para dos propósitos completamente diferentes, la captura es para el manejo de fallas, finalmente es para el manejo de recursos. – james
@james Sí, tienen usos completamente diferentes, lo que significa que su alcance también debería ser diferente. –