Creo que willcode es lo más cercano a expresar el punto clave aquí, y probablemente todos lo quieran decir pero no están claros.
El problema es que de hecho hay algo muy mal con lo que está preguntando: "Si escribo todas las instrucciones después del bloque catch en lugar de escribirlas en el bloque finally entonces ¿habría algo mal?"
Si escribe todas las declaraciones después de que el bloque catch, lo que está dando a entender es que
1) Siempre detectar la excepción.
2) Siempre se continúe con el siguientes declaraciones después de detectar la excepción.
Esto implica que siempre se continuará la ejecución "normalmente" después de una excepción, que es generalmente algo que nunca de hecho quiero hacer.
Las excepciones deberían ser solo eso: excepcionales. Si de hecho puede manejar una excepción, siempre es mejor escribir su código para considerar esas condiciones primero y no dar lugar a ninguna excepción. Si sigue este modelo, las excepciones son realmente excepcionales, condiciones que no podría anticipar o, como máximo, no solucionar. Realmente no anticipar es para lo que debes trabajar. Esto significa que en general no puede manejar excepciones verdaderas, lo que también significa que no debe continuar la ejecución, a menudo termina la aplicación.
Lo que normalmente se hace es permitir un error para propagar una copia de seguridad de la pila de llamadas. Algunos dicen que esto se hace en la posibilidad de que alguien más arriba en la cadena pueda ser capaz de manejarlo. Yo diría que esencialmente nunca sucede, hay dos propósitos reales para hacer esto. Uno puede ser algo que el usuario puede arreglar, si hay uno. Por lo tanto, usted propaga la copia de seguridad de error hasta llegar a donde puede informarlo al usuario. O dos, un usuario no puede arreglarlo, pero desea obtener toda la pila de llamadas para la depuración. Luego lo atrapa en la parte superior para fallar con gracia.
El bloque finally ahora debería tener más significado para usted. Como todo el mundo dice que siempre se ejecuta. El uso más claro de un finalmente está realmente en un intento ... finalmente bloquear. Lo que estás diciendo ahora es si el código funciona bien, genial. Todavía tenemos que hacer un poco de limpieza y, finalmente, siempre se ejecuta, seguimos adelante. Pero si se produce una excepción, ahora realmente necesitamos ese bloqueo final porque es posible que aún tengamos que hacer una limpieza, pero ya no estamos detectando la excepción aquí, así que ya no vamos a seguir avanzando. El bloqueo final es esencial para garantizar la limpieza.
La idea de una excepción que siempre detiene la ejecución puede ser difícil de entender para alguien hasta que tenga una cierta cantidad de experiencia, pero esa es, de hecho, la manera de hacer siempre las cosas. Si ocurrió un error, o era tan pequeño que debiste haberlo contado para empezar, o de lo contrario hay cada vez más errores esperando que ocurra en el futuro.
"Deglución" de errores: atraparlos y seguir adelante es lo peor que puede hacer porque su programa se vuelve impredecible y no puede encontrar y corregir errores.
El código bien escrito contendrá tantos bloques try ... finally como sean necesarios para garantizar que los recursos siempre se liberen sin importar el resultado. Pero el código bien escrito generalmente contiene solo un pequeño número de try ... catch blocks que existen principalmente para permitir que una aplicación falle tan elegantemente como sea posible, o diferir para el usuario, lo que significa al menos pasar un mensaje al usuario, etc. Pero generalmente no solo captas un error y sigues adelante.
Esta pregunta ha sido respondida antes de http://stackoverflow.com/questions/3354823/how-to-use-finally. Así que es un duplicado –
[¡Se garantiza que se ejecute el código en un bloque finally! ¡Siempre! ¡Sin excepciones!] (Http://thedailywtf.com/Articles/My-Tales.aspx) – badp
@Shervin, había leído ambas preguntas antes de marcar como duplicado –