¿Cuál es el punto del último bloque?


Sintaxis aparte, ¿cuál es la diferencia entre

try {
}
catch() {
}
finally {
    x = 3;
}

Y

try {
}
catch() {
}

x = 3;

Editar: ¿en. NET 2.0?


So

try {
    throw something maybe
    x = 3
}
catch (...) {
    x = 3
}

¿Es el comportamiento equivalente?

Author: Bill the Lizard, 2008-09-09

15 answers

Depende del lenguaje, ya que puede haber algunas ligeras diferencias semánticas, pero la idea es que se ejecutará (casi) siempre, incluso si el código en el bloque try lanzó una excepción.

En el segundo ejemplo, si el código en el bloque catch regresa o se cierra, el x = 3 no se ejecutará. En la primera lo hará.

En la plataforma. NET, en algunos casos la ejecución del bloque finally no se producirá: Excepciones de seguridad, suspensiones de hilo, Apagado del ordenador:), etc.

 32
Author: Vinko Vrsalovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:55:23

Bueno, por un lado, si VUELVES dentro de tu bloque try, el finally seguirá ejecutándose, pero el código que aparece debajo del bloque try-catch-finally no lo hará.

 37
Author: Josh Hinman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:43:44

En Java:

Finalmente siempre se llama, independientemente de si la excepción fue capturada correctamente en catch(), o de hecho si tiene un catch en absoluto.

 10
Author: SCdF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 21:19:49

Try catch finalmente es una construcción bastante importante. Puede estar seguro de que incluso si se lanza una excepción, el código en finally block se ejecutará. Es muy importante en el manejo de recursos externos para liberarlos. La recolección de basura no hará eso por ti. En finally part no deberías tener declaraciones return o excepciones throw. Es posible hacer eso, pero es una mala práctica y puede conducir a resultados impredecibles.

Si intentas esto ejemplo:

try {
  return 0;
} finally {
  return 2;
}

El resultado será 2:)

Comparación con otros idiomas: Volver De Finally

 9
Author: Bartosz Bierkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-09 16:53:20

Hay varias cosas que hacen útil un bloque finally:

  1. Si regresa de los bloques try o catch, el bloque finally se sigue ejecutando, justo antes de que se devuelva el control a la función que llama
  2. Si se produce una excepción dentro del bloque catch, o se produce un tipo de excepción no capturada en el bloque try, el código en el bloque finally se sigue ejecutando.

Estos hacen que finalmente los bloques sean excelentes para cerrar manijas de archivos o sockets.

 5
Author: wvdschel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 21:11:15

En el caso de que el try y el catch estén vacíos, no hay diferencia. De lo contrario, puede estar seguro de que finalmente se ejecutará.

Si, por ejemplo, lanza una nueva Excepción en su bloque de captura (rethrow), la asignación solo se ejecutará si está en el bloque finally.

Normalmente se usa finalmente para limpiar después de ti mismo (cerrar conexiones DB, Manejadores de archivos y similares).

Nunca debe usar instrucciones de control (return, break, continue) en a finalmente, ya que esto puede ser una pesadilla de mantenimiento y por lo tanto se considera una mala práctica

 2
Author: Mo.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:44:17

El bloque final siempre será llamado (bueno, no realmente siempre... ) incluso si se lanza una excepción o se alcanza una sentencia return (aunque eso puede depender del idioma). Es una forma de limpiar que sabes que siempre se llamará.

 1
Author: Moe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:46:31

@iAn y @ mats:

No "derribaría" nada en finally {} que estuviera "configurado" dentro del try {} como regla. Sería mejor tirar de la creación de flujo fuera del try {}. Si necesita manejar una excepción en stream create, esto podría hacerse en un ámbito mayor.

StreamReader stream = new StreamReader("foo.bar");  
try {
    mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally {
    stream.close();  
}
 1
Author: Sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-09 16:05:45

Para que pueda limpiar cualquier conexión abierta, etc. inicializado en el bloque try. Si abrió una conexión y luego se produjo una excepción, esa excepción no se cerraría correctamente. Este tipo de escenario es para lo que está el bloque finally.

 0
Author: Ryan Lanciaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:42:32

Se supone que el bloque finally se ejecuta, ya sea que haya capturado la excepción o no. Ver Try / Catch / Finally ejemplo

 0
Author: NotMe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:44:04

@Ed , usted podría estar pensando en algo como un catch(...) que captura una excepción no especificada en C++.

Pero finally es el código que se ejecutará sin importar lo que suceda en los bloques catch.

Microsoft tiene una página de ayuda en try-finally para C #

 0
Author: crashmstr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:16:48

El bloque finally está en el mismo ámbito que el try/catch, por lo que tendrá acceso a todas las variables definidas dentro.

Imagine que tiene un manejador de archivos, esta es la diferencia en cómo se escribiría.

try
{
   StreamReader stream = new StreamReader("foo.bar");
   stream.write("foo");
}
catch(Exception e) { } // ignore for now
finally
{
   stream.close();
}

Comparado con

StreamReader stream = null;
try
{
    stream = new StreamReader("foo.bar");
    stream.write("foo");
} catch(Exception e) {} // ignore

if (stream != null)
    stream.close();

Recuerde sin embargo que cualquier cosa dentro finalmente no está garantizada para funcionar. Imagine que recibe una señal de aborto, Windows se bloquea o la energía se ha ido. Confiar en finalmente para el código crítico de negocio es malo.

 0
Author: Mats Fredriksson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:57:43

Cualquier código en el finally se ejecuta en el even en el caso de una excepción no controlada. Por lo general, el código finally se utiliza para limpiar declaraciones locales de código no administrado utilizando .disponer().

 0
Author: osp70,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 20:59:45

Finalmente, los bloques le permiten, como desarrollador, ordenar después de sí mismo, independientemente de las acciones de código que preceden en el bloque try{} errores encontrados, y otros han señalado esto, se cae principalmente bajo el paraguas de liberar recursos - cerrando punteros / sockets / conjuntos de resultados, devolviendo conexiones a un grupo, etc.

@mats es muy correcto que siempre existe el potencial de fallas "duras": finalmente, los bloques no deberían incluir código de misión crítica, que debería siempre se debe hacer transaccionalmente dentro del try {}

@mats de nuevo - La verdadera belleza es que le permite tirar excepciones de sus propios métodos, y aún así garantizar que usted ordena:

try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally
{
stream.close();
}

Por lo tanto, podemos capturar muchos tipos de excepción, procesarlos de manera diferente (el primero permite la ejecución de cualquier cosa más allá del try{}, el segundo efectivamente devuelve), pero siempre limpia y ordenadamente.

 0
Author: Ian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 21:10:33

En Java, lo usa para cualquier cosa que desee ejecutar independientemente de si usó un "return", simplemente corrió a través del bloque try, o tuvo una excepción atrapada.

Por ejemplo, cerrar una sesión de base de datos o una conexión JMS, o desasignar algún recurso del sistema operativo.

Supongo que es similar en. NET?

 0
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-27 23:49:04