Teniendo en cuenta este código, ¿puedo estar absolutamente seguro de que el finallybloque siempre se ejecuta, sin importar lo que something()sea?
try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}
                    
                        java
                                error-handling
                                return
                                try-catch-finally
                                
                    
                    
                        jonny cinco
fuente
                
                fuente

probablyen su lugar.finally; finalizador == elfinalize()método.Respuestas:
Sí,
finallyse llamará después de la ejecución de los bloques de códigotryocatch.Los únicos momentos
finallyque no se llamarán son:System.exit()Runtime.getRuntime().halt(exitStatus)tryocatchkill -9 <pid>en UNIXfinallybloque va a ser ejecutado por un subproceso de demonio y todos los demás subprocesos que no son de demonio salen antes,finallyse llamafuente
thread.stop(), no necesariamente evitafinallyque se ejecute el bloque.finallybloque se llamará después deltrybloque y antes de que el control pase a las siguientes declaraciones? Eso es consistente con el bloque try que involucra un ciclo infinito y, por lo tanto, el bloque finalmente nunca se invoca.Código de ejemplo:
Salida:
fuente
finallycláusula -conreturn 2;(Error del compilador).Además, aunque es una mala práctica, si hay una declaración de devolución dentro del bloque finalmente, prevalecerá sobre cualquier otra devolución del bloque regular. Es decir, el siguiente bloque devolvería falso:
Lo mismo con lanzar excepciones desde el último bloque.
fuente
Aquí están las palabras oficiales de la Especificación del lenguaje Java.
14.20.2. Ejecución de try-finally y try-catch-finally
La especificación para
returnrealmente hace esto explícito:JLS 14.17 La declaración de devolución
fuente
Además de las otras respuestas, es importante señalar que 'finalmente' tiene el derecho de anular cualquier excepción / valor devuelto por el bloque try..catch. Por ejemplo, el siguiente código devuelve 12:
Del mismo modo, el siguiente método no arroja una excepción:
Si bien el siguiente método lo arroja:
fuente
OutOfMemoryError? ;)return retValdespués delfinallybloque, aunque eso, por supuesto, supone que suprimió algunas otras excepciones porque el código no tendría sentido de otra manera.Intenté el ejemplo anterior con una ligera modificación.
Las salidas del código anterior:
Esto se debe a que cuando
return i;se ejecutaitiene un valor 2. Después de esto, elfinallybloque se ejecuta donde se asigna 12iy luegoSystem.outse ejecuta out.Después de ejecutar el
finallybloque, eltrybloque devuelve 2, en lugar de devolver 12, porque esta declaración de retorno no se ejecuta nuevamente.Si va a depurar el código en Eclipse entonces obtendrá una sensación de que después de la ejecución
System.outdelfinallybloque de lareturndeclaración deltrybloque se ejecuta de nuevo. Pero este no es el caso. Simplemente devuelve el valor 2.fuente
ino fuera un primitivo, sino un objeto entero?Aquí hay una elaboración de la respuesta de Kevin . Es importante saber que la expresión a devolver se evalúa antes
finally, incluso si se devuelve después.Salida:
fuente
finally. Calcular el valor de retorno (printX()aquí) todavía viene antes.System.out.println("finally trumps return... sort of");conSystem.out.print("finally trumps return in try"); return 42;Esa es la idea de un bloque finalmente. Te permite asegurarte de hacer limpiezas que de otro modo podrían saltarse porque regresas, entre otras cosas, por supuesto.
Finalmente se llama independientemente de lo que ocurra en el bloque de prueba (a menos que llame
System.exit(int)o la máquina virtual Java se apague por alguna otra razón).fuente
Una forma lógica de pensar en esto es:
fuente
finalmente siempre se ejecuta a menos que haya una terminación anormal del programa (como llamar a System.exit (0) ..). entonces, tu sysout se imprimirá
fuente
También un retorno finalmente rechazará cualquier excepción. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
fuente
El último bloque siempre se ejecuta a menos que haya una terminación anormal del programa, ya sea como resultado de un bloqueo de JVM o de una llamada a
System.exit(0).Además de eso, cualquier valor devuelto desde dentro del último bloque anulará el valor devuelto antes de la ejecución del último bloque, por lo tanto, tenga cuidado de verificar todos los puntos de salida cuando use try finally.
fuente
No, no siempre un caso de excepción es // System.exit (0); antes de que finalmente el bloque impida finalmente ser ejecutado.
fuente
Finalmente, siempre se ejecuta ese es el punto, solo porque aparece en el código después de la devolución no significa que así es como se implementa. El tiempo de ejecución de Java tiene la responsabilidad de ejecutar este código al salir del
trybloque.Por ejemplo, si tiene lo siguiente:
El tiempo de ejecución generará algo como esto:
Si se produce una excepción no detectada, el
finallybloque se ejecutará y la excepción continuará propagándose.fuente
Esto se debe a que asignó el valor de i como 12, pero no devolvió el valor de i a la función. El código correcto es el siguiente:
fuente
Porque un bloque finalmente siempre se llamará a menos que llame
System.exit()(o el subproceso se bloquea).fuente
De manera concisa, en la documentación oficial de Java (haga clic aquí ), está escrito que:
fuente
ENTRADA:
SALIDA:
fuente
Sí, lo llamarán. Ese es el punto de tener finalmente una palabra clave. Si saltar fuera del bloque try / catch podría saltarse el bloque finalmente, era lo mismo que colocar System.out.println fuera del try / catch.
fuente
Sí, finalmente el bloque siempre se ejecuta. La mayoría de los desarrolladores usan este bloqueo al cerrar la conexión de la base de datos, el objeto del conjunto de resultados, el objeto de la declaración y también los utiliza en la hibernación de Java para revertir la transacción.
fuente
NO SIEMPRE
La especificación del lenguaje Java se describe cómo
try-catch-finallyytry-catchbloques trabajan en 14.20.2En ningún lugar se especifica que el
finallybloque se ejecuta siempre. Pero en todos los casos en los que eltry-catch-finallyytry-finallybloques completos se especifica que antes de la terminaciónfinallydebe ser ejecutado.El JLS no garantiza que FIN se ejecute después de CODE . El JLS garantiza que si se ejecutan CODE y NEXT , FIN siempre se ejecutará después de CODE y antes de NEXT .
¿Por qué JLS no garantiza que el
finallybloque siempre se ejecute después deltrybloque? Porque es imposible Es poco probable pero posible que la JVM sea abortada (matar, estrellarse, apagarse) justo después de completar eltrybloque pero antes de la ejecución delfinallybloque. JLS no puede hacer nada para evitar esto.Por lo tanto, cualquier software que, para su correcto comportamiento, dependa de que los
finallybloques se ejecuten siempre después de quetryse completen sus bloques.returnlas instrucciones en eltrybloque son irrelevantes para este problema. Si la ejecución alcanza el código después detry-catch,finallyse garantiza que elfinallybloque se habrá ejecutado antes, con o sinreturninstrucciones dentro deltrybloque.fuente
Sí lo hará No importa lo que ocurra en el bloque try o catch a menos que se llame System.exit () o JVM se bloquee. Si hay alguna declaración de retorno en el (los) bloque (s), finalmente se ejecutará antes de esa declaración de retorno.
fuente
Sí lo hará. El único caso que no será es que JVM salga o se bloquee
fuente
Agregar a la respuesta de @ vibhash como ninguna otra respuesta explica lo que sucede en el caso de un objeto mutable como el siguiente.
Saldrá
fuente
Intenté esto, es de un solo hilo.
El
mainThreadestará enwaitestado para siempre, porfinallylo tanto , nunca será llamado ,entonces la salida de la consola no
printString: despuéswait()ofinallyDe acuerdo con @Stephen C, el ejemplo anterior es uno de los 3er caso mencionados aquí :
Agregando algunas más posibilidades de bucle infinito en el siguiente código:
Caso 2: si la JVM se bloquea primero
Ref: ¿Cómo se bloquea un JVM?
Caso 6: si el
finallybloque va a ser ejecutado por un demonioThready se llama a todas las otrasThreadssalidas que no sean demonios antesfinally.salida: Esto no imprime "finalmente", lo que implica que "Finalmente bloque" en "hilo de demonio" no se ejecutó
fuente
Considere el siguiente programa:
A partir de Java 1.8.162, el bloque de código anterior proporciona el siguiente resultado:
Esto significa que usar
finallypara liberar objetos es una buena práctica como el siguiente código:fuente
sb.setLength(0)finalmente?sb = null;solo agrega código innecesario. Entiendo que quiere decir que unfinallybloque es un buen lugar para liberar recursos como una conexión de base de datos o algo así, pero tenga en cuenta que su ejemplo podría confundir a los recién llegados.System.out.println("---AGAIN2---");System.out.println(sb);y ahora está más claro. Tal como estaba, el resultado estaba en contra de su tesis: p También agregué a su respuesta, pero la edición debe ser aceptada por un moderador o alguien así. De lo contrario, puede agregarlosEso es realmente cierto en cualquier idioma ... finalmente siempre se ejecutará antes de una declaración de devolución, sin importar dónde esté esa devolución en el cuerpo del método. Si ese no fuera el caso, el bloque finalmente no tendría mucho significado.
fuente
Además del punto sobre el retorno al reemplazar finalmente un retorno en el bloque try, lo mismo se aplica a una excepción. Un bloque finalmente que arroja una excepción reemplazará una devolución o excepción lanzada desde el bloque try.
fuente
finallyejecutará y eso es seguro.finallyno se ejecutará en los siguientes casos:caso 1 :
Cuando estás ejecutando
System.exit().caso 2:
Cuando tu JVM / Thread se bloquea.
caso 3:
Cuando su ejecución se detiene en el medio manualmente.
fuente
fuente