Hace un bloque finally siempre se ejecuta en Java?

Considerando este código, puedo ser absolutamente seguro de que el finally bloque siempre se ejecuta, no importa lo que something() es?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}
  • Si no, la palabra clave debe ser nombrado probably lugar.
  • posibles duplicados de En Java, devolver el triunfo finalmente?
  • No siempre
  • Eficaz java dice lo contrario, informit.com/articles/article.aspx?p=1216151&seqNum=7
  • finalizador != finally; finalizador == el finalize() método.
  • Correcto, «no siempre» de hecho. Pero, a continuación, usted puede nunca jamás usar la palabra «garantizado» o «siempre».
  • Me gustaría ponerlo de esta manera: el flujo de ejecución siempre pasa a través de, finalmente, antes de que se escapa del try-finally estructura. Si muere en el interior, a continuación, estoy bien con eso, debido a que el principal propósito de, en definitiva, es asegurarse de que las cosas no están mal estado por otras partes del código.

InformationsquelleAutor jonny five | 2008-09-15

47 Kommentare

  1. 2483

    Sí, finally será llamado después de la ejecución de la try o catch bloques de código.

    Las únicas veces finally no será llamado son:

    1. Si se invoca System.exit()
    2. Si la JVM se bloquea primera
    3. Si la JVM llega a un bucle infinito (o cualquier otro que no sea interruptable, no termina de instrucción) en el try o catch bloque
    4. Si el SO por la fuerza, termina el proceso de JVM; por ejemplo, kill -9 <pid> en UNIX
    5. Si el sistema host muere; por ejemplo, fallo de alimentación, error de hardware, el sistema operativo de pánico, et cetera
    6. Si el finally bloque va a ser ejecutado por un demonio hilo y todos los demás no-demonio de hilos de salida antes de finally se llama
    • En realidad thread.stop() no impide necesariamente finally cuadra de ser ejecutado.
    • ¿Podemos decir que la finally bloque será llamado después el try bloque, y antes el control pasa a las siguientes afirmaciones. Que es coherente con el bloque try que implican un bucle infinito y, por tanto, el bloque finally en realidad nunca se invoca.
    • Por @andrzejDoyle definición, volverá success primero antes de ir a finally bloque. Es eso correcto?
    • Decidir que el valor de retorno será el éxito, se ejecuta el bloque finally, a continuación, devuelve el control a la función de llamada. Nada será devuelto si el bloque finally se lanza.
    • también hay otro caso, cuando usamos anidada try-catch-finally bloques
    • también, por último bloque no está llamado en el caso de la excepción lanzada por el demonio de hilo.
    • Pero eficaces java dice lo contrario. informit.com/articles/article.aspx?p=1216151&seqNum=7
    • Esto es bastante interesante que finalmente se llamaría cuando uno se re-lanza su excepción en la captura() como new RuntimeException.
    • Que trata de finalizador, no por último bloque
    • si el hardware/OS se comporta incorrectamente
    • ¿Qué acerca de tiempo de ejecución de#halt ?
    • bloque no está llamado en el caso de la excepción lanzada por el demonio hilo» – ¿de verdad?? [Cita requerida], creo?
    • href=»http://javarevisited.blogspot.in/2012/03/what-is-daemon-thread-in-java-and.html?m=1″ >javarevisited.blogspot.en/2012/03/…
    • href=»https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html» >docs.oracle.com/javase/tutorial/essential/exceptions/…
    • El Oráculo de la página no menciona los demonios en todo. El otro (blogger) página se discute una JVM de la terminación de, pero no van a mostrar la diferencia frente a un no-demonio hilo. La realidad es: en el Sistema.la salida de finalización (incl cierre con ganchos) u otra terminación, todos los hilos de morir sólo cuando están de pie, ya sea demonio o no: no finallys se ejecutan de cualquier manera. El blogger es incorrecto donde se nota esto como una diferencia … pruébelo usted mismo.
    • Correcto. La razón por la que el demonio hilo no se está ejecutando la finally en ese ejemplo es la razón 3). Es en un bucle infinito. Si el bucle no estaba allí, entonces también podría fallar para ejecutar el finally para la razón 1). Cuando main método devuelve (y no hay demonio de hilos) se ejecuta System.exit() … o el equivalente. Línea de base: demonio de hilos NO son una excepción a las razones dadas por la Respuesta anterior.
    • Bucle infinito no es realmente una excepción a la «finalmente se llamará cuando se trate de bloquear los acabados de la regla». Incluso con un bucle infinito en el bloque try, el bloque finally todavía será ejecutar cuando el bloque try acabados, como de costumbre – el bloque try no acabo de finalizar. Este no es un caso especial.
    • «El sistema host muere; por ejemplo,. fallo de alimentación, error de hardware…» no es realmente una excepción a la finalmente, la regla de bloqueo, ya sea. Eso es como «se return 1+1 siempre regreso 2?» «No necesariamente, de una pérdida de alimentación puede dejar de return 1+1 de regresar 2.» … no es realmente una parte de la respuesta. Lo mismo con #4, el kill -9 ejemplo, es suficiente para la #4 y #5, tanto que #2 «JVM accidente» está en la lista, que podría formularse de «JVM termina de manera abrupta» a la mejor coger todas las situaciones.
    • finally también se ejecuta cuando un StackOverflowError es lanzado.
    • JavaSystem.exit(); (como C#o PHP) puede ser confuso para los desarrolladores que vienen de otros lenguajes de programación. En Python sys.exit() plantea un (regular) SystemExit excepción de que puede ser apresado. En Pascal exit es un habitual de control de la instrucción, y finally será ejecutado demasiado.
    • a piggy-back en esto, aunque finally se ejecuta, incluso después de un StackOverflowError, marcos añade a la pila dentro de una finally bloqueo puede causar un inesperado adicionales StackOverflowError, líder de los restantes contenidos de la finally bloque de salta. Por esta razón, StackOverflowError errores puede ser muy peligroso. Recientemente hemos topado con un problema difícil con semáforos, no se publica en un finally bloque por esta misma razón.
    • Q: ¿siempre? R: Sí, pero… Para mí esto significa que el aceptado la respuesta debe ser no. Si hay excepciones para siempre, entonces no. Puede ejecutar la mayoría del tiempo. Pero no siempre. Estoy sorprendido de que yo soy uno de los pocos a reaccionar a esto.
    • También, finalmente no será llamado si el mundo se acaba antes de la ejecución alcanza el bloque finally…
    • Todos los casos cuando no se cuando algo loco pasa como a alguien de la fuerza de matar el proceso, es entrar en un bucle infinito, o el poder de salir. Para mí, si se comporta de una cierta manera, excepto en aquellos más extremo de los casos de borde es bueno decir «sí, siempre, excepto…» en lugar de «no». En realidad, en el caso de un bucle infinito, se ejecutar la finalmente, es sólo que nunca termina lo que está haciendo antes.
    • Si se invoca JNI código que hace ExitThread() …
    • Si la máquina está suspendido. Si el kernel nunca se da otra vez la JVM en tiempo de ejecución. Probablemente hay muchos más casos de borde cuando finalmente no se ejecuta. Esta respuesta da una buena y fácil de entender la explicación. Pero sería más fácil y más simple decir que «Si el bloque try o bloque try-catch completa, a continuación, el bloque finally se ejecuta.» El JLS utiliza el mismo tipo de lenguaje.
    • Alguien puede arrojar más luz sobre el último punto If finally block is going to be executed by daemon thread and all other non daemon threads exit before finally is called.?
    • La JVM sí terminará cuando el último no-demonio subproceso termina (que es la defn de un demonio hilo, por cierto: que no impide que la JVM de la salida). Así que si tu demonio hilo había entrado en la prueba de bloque, y la última no-demonio terminado, entonces la JVM va a salir y que todos los demonios se repentinamente desaparece.

  2. 518

    Ejemplo de código:

    public static void main(String[] args) {
        System.out.println(Test.test());
    }
    
    public static int test() {
        try {
            return 0;
        }
        finally {
            System.out.println("finally trumps return.");
        }
    }

    De salida:

    finally trumps return. 
    0
    • FYI: En C#, el comportamiento es idéntico aparte del hecho de que la sustitución de la declaración en el finally-cláusula con return 2; no está permitido (Compilador-Error).
    • Aquí hay un detalle importante a tener en cuenta: stackoverflow.com/a/20363941/2684342
    • SI AGREGA BLOQUE CATCH, error: missing return statement
    • Usted puede incluso agregar una instrucción return en el bloque finally sí, que luego reemplazar el anterior valor de retorno. Esto también mágicamente desecha las excepciones no controladas. En ese punto, usted debe considerar la refactorización de código.
    • Que en realidad no prueban que finalmente triunfa sobre de retorno. El valor de retorno se imprime a partir de la persona que llama código. No parece ser mucho.
    • Sí, es sólo responder a la pregunta, tal como solicitó. de Tristán respuesta se aclara que el valor de retorno evalúa, el finally bloque se ejecuta y, a continuación, el control se devuelve a la persona que llama.
    • Lo siento, pero esta es una demostración no una prueba. Es sólo una prueba, si usted puede demostrar que este ejemplo siempre se comporta de esta manera en todas las plataformas Java, Y que ejemplos similares también siempre se comportan de esta manera.

  3. 370

    También, aunque es una mala práctica, si hay una sentencia return dentro del bloque finally, que va a triunfar sobre cualquier otra devolución de los regulares del bloque. Es decir, el siguiente bloque devolverá false:

    try { return true; } finally { return false; }

    Lo mismo con lanzar excepciones desde el bloque finally.

    • Esta es una MUY mala práctica. Consulte stackoverflow.com/questions/48088/… para obtener más información acerca de por qué es malo.
    • De acuerdo. Una devolución en un plazo finalmente{} ignora cualquier excepción en try{}. De miedo!
    • No importa qué, siempre tengo SÓLO UNO return declaración en mis métodos (que es al final), excepto cuando su void. Eso es lo que me enseñaron en la escuela y creo que es una mejor práctica.
    • ¿Por qué crees que es una mejor práctica? Y ¿por qué debería ser diferente cuando la función/método es nulo?
    • Por la misma razón que yo NUNCA uso de goto en C++ códigos. Creo que varias devoluciones hace que sea más difícil de leer y más difícil de depurar (por supuesto, en realidad simple de los casos no se aplican). Supongo que sólo personal preferrence y en el final se puede lograr lo mismo mediante el método
    • Yo tiendo a usar un número de devoluciones cuando algún tipo de caso excepcional de que sucede. Como si(existe una razón para no continuar) return;
    • Me interpretar finally bloque como una forma abreviada de escribir el mismo código al final de cada catch bloque: `catch (Exc exc) { doSome(); } catch (AnotherExc exc) { doSome(); }
    • No es lo mismo, porque como la respuesta de los estados, si la finally bloque tiene una instrucción return, se anulará el uno en el catch bloque. Usted puede hacerlo con catch.

  4. 251

    Aquí está el oficial de palabras del Lenguaje Java Especificación.

    14.20.2. La ejecución de try-finally y try-catch-finally

    Un try declaración con un finally bloque es ejecutado por ejecutar primero el try bloque. Entonces no es una opción:

    • Si la ejecución de la try bloque se completa normalmente, […]
    • Si la ejecución de la try bloque finaliza abruptamente debido a un throw de un valor V, […]
    • Si la ejecución de la try bloque finaliza abruptamente por cualquier otra razón R, entonces el finally bloque se ejecuta. Entonces no es una opción:
      • Si el bloque finally se completa normalmente, entonces el try declaración finaliza abruptamente por razón R.
      • Si el finally bloque finaliza abruptamente por razón S, entonces el try declaración finaliza abruptamente por razón S (y la razón R se descarta).

    La especificación para return en realidad hace explícito:

    JLS 14.17 La Instrucción return

    ReturnStatement:
         return Expression(opt) ;

    Un return declaración sin Expression intentos para transferir el control a la invocador del método o constructor que lo contiene.

    Un return declaración con un Expression intentos para transferir el control a la invocador del método que contiene; el valor de la Expression se convierte en el valor de la invocación del método.

    Las anteriores descripciones dicen «intentos para transferir el control» más que de «transfiere el control» porque si hay cualquier try declaraciones dentro del método o constructor cuya try bloques contienen la return declaración, entonces cualquier finally cláusulas de los try declaraciones serán ejecutadas, en fin, más interna a la más externa, antes de que el control se transfiere al invocador del método o constructor. Abrupta terminación de un finally cláusula puede interrumpir la transferencia de control iniciadas por un return declaración.

  5. 151

    Además de las otras respuestas, es importante señalar que ‘finalmente’ tiene el derecho a anular cualquier excepción/valor devuelto por el bloque try..catch. Por ejemplo, el código siguiente devuelve 12:

    public static int getMonthsInYear() {
        try {
            return 10;
        }
        finally {
            return 12;
        }
    }

    Del mismo modo, el siguiente método no se lanza una excepción:

    public static int getMonthsInYear() {
        try {
            throw new RuntimeException();
        }
        finally {
            return 12;
        }
    }

    Mientras que el siguiente método no tirar:

    public static int getMonthsInYear() {
        try {
            return 12;          
        }
        finally {
            throw new RuntimeException();
        }
    }
    • Cabe señalar que la mitad caso es precisamente la razón por la que tener una sentencia return dentro de un bloque finally es absolutamente horrible (se puede ocultar cualquier Arrojadiza).
    • Que no quiero un surpressed OutOfMemoryError? 😉
  6. 110

    He probado el ejemplo anterior con una ligera modificación-

    public static void main(final String[] args) {
        System.out.println(test());
    }
    
    public static int test() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 12;
            System.out.println("finally trumps return.");
        }
    }

    El código anterior salidas:

    finalmente triunfa de retorno.

    2

    Esto es porque cuando return i; se ejecuta i tiene un valor de 2. Después de esto, el finally bloque se ejecuta en donde 12 es asignado a i y, a continuación, System.out fuera ejecutado.

    Después de la ejecución de la finally bloque de la try bloque devuelve 2, en lugar de devolver 12, porque esta instrucción return no se ejecuta de nuevo.

    Si va a depurar este código en Eclipse, a continuación, usted obtendrá una sensación de que después de la ejecución de System.out de finally bloque de la return declaración de try bloque se ejecuta de nuevo. Pero este no es el caso. Simplemente devuelve el valor 2.

    • Este ejemplo es impresionante, se añade algo que no ha sido mencionado en docenas finalmente relacionadas con hilos. Creo que apenas cualquier desarrollador sabrá esto.
    • Lo que si i no era un primitivo, pero un objeto Integer.
    • Estoy teniendo un tiempo difícil la comprensión de este caso. docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17, dice que, «Una instrucción return con una Expresión intentos de transferir el control a la invocador del método o lambda cuerpo que la contiene…. Si la evaluación de la Expresión completa normalmente, la producción de un valor de V..» Lo que yo podía adivinar a partir de esta declaración es – parece que el retorno no evaluar la expresión de nuevo una vez que se evalúa el valor de V, es por eso que he cambiado no afecta el valor devuelto, me corrija.
    • Pero yo coudn no encontró ninguna prueba al respecto, donde se menciona que el retorno no evaluar la expresión de nuevo.
    • un poco tarde, pero es explicado en JLS 14.20.2. La ejecución de try-finally y try-catch-finally redactar un poco complicado, 14.17. La Instrucción return también debe ser leído
    • Yamcha no por Ello deja de ser el mismo
    • Yo creo que si se añade una instrucción return para el bloque finally, el valor devuelto sería de 12, no 2. El ejemplo indica que el bloque finally se inserta en la pila de llamadas exactamente el mismo que el de llamar a un método – que hace una copia local de i, que se vuelve a 2 después de que la pila se apareció.

  7. 101

    Aquí está una elaboración de Kevin respuesta. Es importante saber que la expresión que se devuelve es evaluado antes de finally, incluso si es devuelto después.

    public static void main(String[] args) {
        System.out.println(Test.test());
    }
    
    public static int printX() {
        System.out.println("X");
        return 0;
    }
    
    public static int test() {
        try {
            return printX();
        }
        finally {
            System.out.println("finally trumps return... sort of");
        }
    }

    De salida:

    X
    finally trumps return... sort of
    0
    • Importante saber.
    • Es bueno saberlo, y tiene sentido. Parece ser que en realidad devolver el valor de retorno es lo que viene después finally. Calcular el valor de retorno (printX() aquí) aún antes de ella.
  8. 53

    Que es la idea de un bloque finally. Esto le permite asegurarse de hacer las limpiezas que de lo contrario podría ser omitido porque de volver, entre otras cosas, por supuesto.

    Finalmente llama independientemente de lo que sucede en el bloque try (menos llamar System.exit(int) o la Máquina Virtual de Java patadas por algún otro motivo).

  9. 39

    Una manera lógica de pensar acerca de esto es:

    1. El código colocado en un bloque finally debe ser ejecutado lo que ocurre dentro del bloque try
    2. Así que si el código en el bloque try intenta devolver un valor o lanzar una excepción se coloca el elemento ‘en la estantería hasta que el bloque finally se puede ejecutar
    3. Debido a que el código en el bloque finally se tiene (por definición) una alta prioridad puede devolver o tirar lo que le gusta. En cuyo caso cualquier cosa a la izquierda ‘en la plataforma’ se descarta.
    4. La única excepción a esto es si la máquina virtual se cierra completamente durante el bloque try por ejemplo, por ‘Sistema.la salida’
    • Se trata simplemente de «una forma lógica para pensar en ello», o es que realmente la forma en la que el bloque finally es la intención de trabajar de acuerdo a las especificaciones ? Un enlace a un Sol de recursos sería muy interesante aquí.
    • stackoverflow.com/a/65049/715269
  10. 19

    finalmente se ejecuta siempre a menos que haya anormal de finalización del programa (como el Sistema de llamadas.exit(0)..). así, su sysout aparecerá escrito

  11. 18

    El bloque finally siempre se ejecuta a menos que haya anormales de terminación del programa, o resultantes de una JVM accidente o de una llamada a System.exit(0).

    En la parte superior de que, cualquier valor que se devuelve desde dentro del bloque finally reemplazar el valor devuelto antes de la ejecución del bloque finally, así que tenga cuidado de comprobar todos los puntos de salida cuando se utiliza intentar finalmente.

  12. 18

    No, no siempre, un caso de excepción es//
    Sistema.exit(0);
    antes de que el bloque finally se evita, finalmente, a ser ejecutado.

      class A {
        public static void main(String args[]){
            DataInputStream cin = new DataInputStream(System.in);
            try{
                int i=Integer.parseInt(cin.readLine());
            }catch(ArithmeticException e){
            }catch(Exception e){
               System.exit(0);//Program terminates before executing finally block
            }finally{
                System.out.println("Won't be executed");
                System.out.println("No error");
            }
        }
    }
    • Y esa es una de las razones por las que usted realmente nunca debe llamar Sistema.exit()…
  13. 13

    Finalmente siempre se ejecuta, que es el punto entero, sólo porque aparece en el código después de que el retorno no significa que eso es cómo se implementa. El tiempo de ejecución de Java tiene la responsabilidad de ejecutar este código al salir de la try bloque.

    Por ejemplo, si usted tiene los siguientes:

    int foo() { 
        try {
            return 42;
        }
        finally {
            System.out.println("done");
        }
    }

    El tiempo de ejecución va a generar algo como esto:

    int foo() {
        int ret = 42;
        System.out.println("done");
        return 42;
    }

    Si una excepción no capturada se produce la finally bloque se ejecutará y la excepción se seguirá propagando.

  14. 11

    Esto es debido a que se asignó el valor de i como de 12, pero no devolver el valor de la i a la función. El código correcto es el siguiente:

    public static int test() {
        int i = 0;
        try {
            return i;
        } finally {
            i = 12;
            System.out.println("finally trumps return.");
            return i;
        }
    }
  15. 10

    Porque un bloque finally siempre se llamó a menos que se llame System.exit() (o el hilo se bloquea).

  16. 10

    Respuesta es simple .

    De ENTRADA:

    try{
        int divideByZeroException = 5 / 0;
    } catch (Exception e){
        System.out.println("catch");
        return;    //also tried with break; in switch-case, got same output
    } finally {
        System.out.println("finally");
    }

    De SALIDA:

    catch
    finally
    • La respuesta es simple NO.
    • Cómo? Puede usted explicar por favor?
    • leer el aceptado la respuesta, la pregunta original es acerca de «¿Va a ejecutar siempre’ y no siempre será así. En tu caso, pero esto no responde a la pregunta original, e incluso puede ser engañosa los principiantes.
    • a continuación, caso en el cual no puedo conseguir ejecutar?
    • En todos los casos mencionados en otras respuestas, ver aceptado responder con 1000+ upvotes.
  17. 9

    Sí será llamado. Ese es el punto de tener finalmente un palabra clave. Si de saltar fuera del bloque try/catch sólo se pudo omitir el bloque finally se fue la misma que la de poner el Sistema.a cabo.println fuera del try/catch.

  18. 9

    De manera concisa, en la Documentación oficial de Java (haga Clic en aquí), está escrito que –

    Si la JVM salidas, mientras que el try o catch código se está ejecutando, entonces
    el bloque finally no se puede ejecutar. Del mismo modo, si el hilo de ejecución
    el try o catch código se interrumpe o se mató, el bloque finally se puede
    no ejecutar incluso aunque la aplicación como un todo continúa.

  19. 9

    Sí, bloque finally siempre se ejecuta. La mayoría de los desarrolladores el uso de este bloque, el cierre de la conexión de base de datos, objeto resultset, declaración de objetos y también se utiliza en el java hibernate para deshacer la transacción.

  20. 8

    Sí, lo hará. No importa lo que sucede en su bloque try o catch a menos que de lo contrario el Sistema.exit() se llama o JVM se estrelló. si hay alguna instrucción return en el bloque(s),finalmente será ejecutado antes de que la instrucción return.

  21. 8

    Añadir a @vibhash la respuesta como ninguna otra respuesta explica lo que sucede en el caso de un objeto mutable como la de abajo.

    public static void main(String[] args) {
        System.out.println(test().toString());
    }
    
    public static StringBuffer test() {
        StringBuffer s = new StringBuffer();
        try {
            s.append("sb");
            return s;
        } finally {
            s.append("updated ");
        }
    }

    De salida será de

    sbupdated 
    • Como de Java 1.8.162, esta no es la salida.
  22. 8

    Considere el siguiente programa:

    public class SomeTest {
    
        private static StringBuilder sb = new StringBuilder();
    
        public static void main(String args[]) {
    
            System.out.println(someString());
            System.out.println("---AGAIN---");
            System.out.println(someString());
            System.out.println("---PRINT THE RESULT---");
            System.out.println(sb.toString());
        }
    
        private static String someString() {
    
            try {
                sb.append("-abc-");
                return sb.toString();
    
            } finally {
                sb.append("xyz");
            }
        }
    }

    De Java 1.8.162, el anterior bloque de código que da el siguiente resultado:

    -abc-
    ---AGAIN---
    -abc-xyz-abc-
    ---PRINT THE RESULT---
    -abc-xyz-abc-xyz

    esto significa que el uso de finally para liberar los objetos es una buena práctica como el código siguiente:

    private static String someString() {
    
        StringBuilder sb = new StringBuilder();
    
        try {
            sb.append("abc");
            return sb.toString();
    
        } finally {
            sb = null; //Just an example, but you can close streams or DB connections this way.
        }
    }
    • No debería ser sb.setLength(0) finalmente?
    • sb.setLength(0), se acaba de vaciar los datos en el StringBuffer. Así, sb = null disociar el objeto de la referencia.
    • No debería «xyz» se imprime dos veces en la salida? Ya que la función ha llamado dos veces, ¿por qué «finalmente» fue sólo una vez?
    • finalmente es, sin duda llamó dos veces, pero cuando se trata de la salida en la consola solo se mostrará una vez, a causa de la instrucción return. Usted puede ejecutar el programa y ver la salida, y después de que agregar otra declaración System.out.println(sb.toString());
    • Esta no es una buena práctica. Que por último bloque con sb = null; sólo añade innecesarios código. Entiendo que te refieres a que un finally bloque es un buen lugar para liberar recursos como una conexión de base de datos o algo así, pero tenga en mente que su ejemplo podría confundir a los recién llegados.
    • de acuerdo. Voy a editar mi respuesta.
    • Gracias, he añadido las líneas System.out.println("---AGAIN2---"); System.out.println(sb); y es más claro ahora. Como lo fue, la salida fue en contra de su tesis :p yo también se ha añadido a tu respuesta, pero la edición que deberán ser aceptadas por un moderador o alguien así. Otra cosa que usted puede agregar

  23. 7

    Que es cierto en cualquier idioma…finally siempre se ejecuta antes de una instrucción return, no importa dónde que el regreso sea en el cuerpo del método. Si ese no era el caso, el bloque finally no tendría mucho sentido.

    • No se de que cada lengua tiene finally en el primer lugar…
  24. 7

    Además de un punto de devolución finalmente la colocación de un retorno en el bloque try, el mismo es cierto de una excepción. Finalmente un bloque que lanza una excepción reemplazará a un retorno o de excepción desde dentro del bloque try.

  25. 7

    finally se va a ejecutar y que es seguro.

    finally no se ejecutará en los siguiente casos:

    caso 1 :

    Cuando se ejecutan System.exit().

    caso 2 :

    Cuando su JVM /Thread se bloquea.

    caso 3 :

    Cuando su ejecución se detiene en entre manualmente.

  26. 6
    1. Bloque Finally siempre se ejecuta. A menos que y hasta que
      Sistema.exit() declaración existe (primera instrucción del bloque finally).
    2. Si sistema.exit() es la primera declaración, a continuación, por último bloque no se ejecutan y control de salir del bloque finally.
      Siempre Que Sistema.instrucción exit() obtiene en el bloque finally hasta que la declaración de bloque finally se ejecuta y cuando el Sistema.exit() que aparece a continuación, el control de la fuerza de salir en su totalidad del bloque finally.
    • Esto ha sido contestado muchas veces, de modo que la nueva información no añadir tu respuesta?
  27. 6

    Si no se manejan de excepción, antes de terminar el programa, la JVM ejecuta el bloque finally. No se ejecuta sólo si la ejecución normal del programa producirá un error significa la terminación del programa debido a las siguientes razones..

    1. Causando un grave error que hace que el proceso de anulación.

    2. La terminación del programa debido a la memoria corrupta.

    3. Por el Sistema de llamadas.exit()

    4. Si el programa entra en bucle infinito.

  28. 6

    Sí, porque ninguna sentencia de control de puede prevenir finally de ser ejecutado.

    Aquí es un ejemplo de referencia, donde todos los bloques de código se ejecuta:

    | x | Current result | Code 
    |--- | ---------------- | ------ - - -
    |   |                |     
    |   |                | public static int finallyTest() {
    | 3 |                |     int x = 3;
    |   |                |     try {
    |   |                |        try {
    | 4 |                |             x++;
    | 4 | return 4       |             return x;
    |   |                |         } finally {
    | 3 |                |             x--;
    | 3 | throw          |             throw new RuntimeException("Ahh!");
    |   |                |         }
    |   |                |     } catch (RuntimeException e) {
    | 4 | return 4       |         return ++x;
    |   |                |     } finally {
    | 3 |                |         x--;
    |   |                |     }
    |   |                | }
    |   |                |
    |--- | ---------------- | ------ - - -
    |   | Result: 4      |

    En la variante a continuación, return x; serán omitidos. El resultado es todavía 4:

    public static int finallyTest() {
        int x = 3;
        try {
            try {
                x++;
                if (true) throw new RuntimeException("Ahh!");
                return x; //skipped
            } finally {
                x--;
            }
        } catch (RuntimeException e) {
            return ++x;
        } finally {
            x--;
        }
    }

    Referencias, por supuesto, el seguimiento de su estado. Este ejemplo devuelve una referencia con value = 4:

    static class IntRef { public int value; }
    public static IntRef finallyTest() {
        IntRef x = new IntRef();
        x.value = 3;
        try {
            return x;
        } finally {
            x.value++; //will be tracked even after return
        }
    }
  29. 6

    NO SIEMPRE

    El Lenguaje Java especificación describe cómo try-catch-finally y bloques try-catch trabajo en 14.20.2

    En ningún lugar se especifica que el bloque finally se ejecuta siempre.
    Pero para todos los casos en los que el try-catch-finally y bloques try-finally completa no especifica que antes de la finalización finalmente debe ser ejecutado.

    try {
      CODE inside the try block
    }
    finally {
      FIN code inside finally block
    }
    NEXT code executed after the try-finally block (may be in a different method).

    El JLS no garantiza que ALETA es ejecutado después de haber CÓDIGO.
    El JLS garantiza que si CÓDIGO y SIGUIENTE se ejecutan, a continuación, ALETA siempre se ejecutará después de CÓDIGO y antes de SIGUIENTE.

    ¿Por qué no la JLS garantía de que el bloque finally se ejecuta siempre después del bloque try? Porque es imposible. Es improbable pero posible que la JVM va a ser abortado (matar, bloqueo, apagado) justo después de terminar el bloque try, pero antes de la ejecución del bloque finally. No hay nada que el JLS puede hacer para evitar esto.

    Por lo tanto, cualquier software que para su adecuado comportamiento depende de bloques finally siempre se ejecuta después de que sus trate de bloques completos son intervenidos.

    Devuelve en el bloque try son irrelevantes para este problema. Si la ejecución llega el código después del try-catch-finally se garantiza que el bloque finally se han ejecutado antes, con o sin devoluciones dentro del bloque try.

  30. 6

    He probado este,
    Es de un solo subproceso.

    class Test {
        public static void main(String args[]) throws Exception {
           Object obj = new Object();
           try {
                synchronized (obj) {
                obj.wait();
                System.out.println("after wait()");
               }
           } catch (Exception e) {
           } finally {
               System.out.println("finally");
           }
       }
    }

    El hilo principal estará en estado de espera para siempre, de ahí que finalmente nunca será llamado,

    para la salida de la consola no la cadena de impresión: after wait() o finally

    De acuerdo con @Esteban C, el ejemplo anterior es uno de los 3 de caso mencionar aquí:

    Añadir algunos más, tales bucle infinito de posibilidades en el código siguiente:

    //import java.util.concurrent.Semaphore;
    class Test {
        public static void main(String[] args) {
            try {
                //Thread.sleep(Long.MAX_VALUE);
                //Thread.currentThread().join();
                //new Semaphore(0).acquire();
                //while (true){}
                System.out.println("after sleep join semaphore exit infinite while loop");
            } catch (Exception e) {
            } finally {
                System.out.println("finally");
            }
        }
    }

    Caso 2: Si la JVM se bloquea primera

    import sun.misc.Unsafe;
    import java.lang.reflect.Field;
    class Test {
        public static void main(String args[]) {
            try {
                unsafeMethod();
    //           Runtime.getRuntime().halt(123);
                System.out.println("After Jvm Crash!");
            } catch (Exception e) {
            } finally {
                System.out.println("finally");
            }
        }
    
        private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            Unsafe unsafe = (Unsafe) f.get(null);
            unsafe.putAddress(0, 0);
        }
    }

    Ref: Cómo hacer que choque con una JVM?

    Caso 6: Si finalmente el bloque que va a ser ejecutado por un demonio hilo y todos los demás no-demonio de hilos de salida antes de que finalmente se llama.

    class Test {
        public static void main(String args[]) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        printThreads("Daemon Thread printing");
                        //just to ensure this thread will live longer than main thread
                        Thread.sleep(10000);
                    } catch (Exception e) {
                    } finally {
                        System.out.println("finally");
                    }
                }
            };
            Thread daemonThread = new Thread(runnable);
            daemonThread.setDaemon(Boolean.TRUE);
            daemonThread.setName("My Daemon Thread");
            daemonThread.start();
            printThreads("main Thread Printing");
        }
    
        private static synchronized void printThreads(String str) {
            System.out.println(str);
            int threadCount = 0;
            Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
            for (Thread t : threadSet) {
                if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
                    System.out.println("Thread :" + t + ":" + "state:" + t.getState());
                    ++threadCount;
                }
            }
            System.out.println("Thread count started by Main thread:" + threadCount);
            System.out.println("-------------------------------------------------");
        }
    }

    de salida: no impresión «finalmente», que implica «bloque Finally» en «demonio hilo de» no ejecutar

    main Thread Printing  
    Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED  
    Thread :Thread[main,5,main]:state:RUNNABLE  
    Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE   
    Thread count started by Main thread:3  
    -------------------------------------------------  
    Daemon Thread printing  
    Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE  
    Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE  
    Thread count started by Main thread:2  
    -------------------------------------------------  
    
    Process finished with exit code 0
    • Ver la aceptación respuesta. Este es sólo un caso extremo de «bucle infinito».
  31. 5

    El bloque finally no será llamado después de volver en un par de escenarios únicos: si Sistema.exit() es llamado en primer lugar, o si la JVM se bloquea.

    Permítanme tratar de responder a su pregunta en la forma más fácil posible.

    Regla 1 : El bloque finally siempre se ejecuta
    (Aunque hay excepciones. Pero atengámonos a esto por algún tiempo.)

    Regla 2 : las declaraciones en el bloque finally se ejecuta cuando las hojas de control de un intento o un bloque catch.La transferencia de control puede ocurrir como resultado de la ejecución normal de ejecución de una pausa , continuar, ir o una instrucción return, o de una propagación de una excepción.

    En caso de una instrucción return específicamente (desde su subtítulos), el control tiene que salir el método de llamada , Y por lo tanto llama a la por último bloque de la correspondiente try-finally estructura. La instrucción return se ejecuta después de que el bloque finally.

    En caso de que haya una instrucción return en el bloque finally también, sin duda reemplazar la pendiente en el bloque try , ya que su limpieza de la pila de llamadas.

    Puede referir a un mejor explicación aquí : http://msdn.microsoft.com/en-us/…. el concepto es principalmente mismo en todos los lenguajes de alto nivel.

  32. 5

    trycatchfinally son las palabras clave para utilizar el manejo de excepciones del caso.

    Como normal explanotory

    try {
         //code statements
         //exception thrown here
         //lines not reached if exception thrown
    } catch (Exception e) {
        //lines reached only when exception is thrown
    } finally {
        //always executed when the try block is exited
        //independent of an exception thrown or not
    }

    El bloque finally evitar la ejecución de…

    • Cuando usted llama a System.exit(0);
    • Si JVM salidas.
    • Errores en la JVM
  33. 4

    Si se produce una excepción, finalmente se ejecuta. Si la excepción no está lanzado, finalmente se ejecuta. Si la excepción es capturada, finalmente se ejecuta. Si la excepción no está atrapado, finalmente se ejecuta.

    Único momento en que no se ejecuta es cuando la JVM salidas.

  34. 4

    Prueba este código, se entiende la código en el bloque finally se ejecuta después de la instrucción return.

    public class TestTryCatchFinally {
        static int x = 0;
    
        public static void main(String[] args){
            System.out.println(f1() );
            System.out.println(f2() );
        }
    
        public static int f1(){
            try{
                x = 1;
                return x;
            }finally{
                x = 2;
            }
        }
    
        public static int f2(){
            return x;
        }
    }
  35. 4

    Bloque Finally siempre se ejecuta si el identificador de excepción o no .si cualquier excepción se produjo antes de bloque try, finalmente, el bloque no se ejecutará.

  36. 4

    Yo estaba muy confundida con todas las respuestas que se dieron en diferentes foros y decidió finalmente código y ver. La salida es :

    finalmente serán ejecutadas, incluso si no hay retorno en try y catch block.

    try {  
      System.out.println("try"); 
      return;
      //int  i =5/0;
      //System.exit(0 ) ;
    } catch (Exception e) {   
      System.out.println("catch");
      return;
      //int  i =5/0;
      //System.exit(0 ) ;
    } finally {  
       System.out.println("Print me FINALLY");
    }

    Salida

    intentar

    Impresión de mí FINALMENTE

    1. Si el retorno es reemplazado por System.exit(0) en try y catch bloque de código anterior y se produce una excepción antes de que,por cualquier razón.
  37. 4

    Sí, está escrito aquí

    Si la JVM salidas, mientras que el try o catch código se está ejecutando, entonces, el bloque finally no se puede ejecutar. Del mismo modo, si el subproceso que ejecuta el try o catch código se interrumpe o se mató, el bloque finally no se puede ejecutar incluso aunque la aplicación como un todo continúa.

    • Así que cuando usted dice que sí dices que no?
    • Así que estás en lo correcto.
  38. 3

    Porque el final siempre es ser llamado en cualquier de los casos usted tiene. Usted no tiene excepción, aún se llama, la captura de la excepción, aún se llama

  39. 3

    Considerar esto en un curso normal de ejecución (he.e sin ninguna Excepción): si el método no está «vacío», a continuación, siempre explícitamente devuelve algo, sin embargo, finalmente siempre se ejecuta

  40. 3

    Mismo con el siguiente código:

    static int f() {
        while (true) {
            try {
                return 1;
            } finally {
                break;
            }
        }
        return 2;
    }

    f devolverá 2!

    • La duplicación de respuesta
  41. 3

    Sí es siempre llamado, pero en una situación que no llame al uso del Sistema.exit()

    try{
    //risky code
    }catch(Exception e){
    //exception handling code
    }
    finally(){
    //It always execute but before this block if there is any statement like System.exit(0); then this block not execute.
    }
    • La duplicación de respuesta
    • No sólo ‘duplicación’ pero la auto-contradictoria.
  42. 3

    por último también se puede salido antes de tiempo si se produce una excepción dentro de un entramado bloque finally. El compilador le advertirá de que el bloque finally no se completa normalmente o dar un error que tiene código inalcanzable. El error para inalcanzable código se muestra sólo si el tiro no está detrás de una instrucción condicional o dentro de un bucle.

    try{
    }finally{
       try{
       }finally{
          //if(someCondition) --> no error because of unreachable code
          throw new RunTimeException();
       }
       int a = 5;//unreachable code
    }
    • Sólo señalar que esto es completamente normal comportamiento. Cualquier/todo el código que sale de forma prematura si se produce una excepción. Esto no es diferente de una excepción que en cualquier otro lugar. No hay ninguna regla especial en la especificación que dice: «las excepciones no pueden ser utilizados dentro de un bloque finally.» Debido a esto, incluso he entendido mal tu respuesta en primera y casi dio -1, hasta que he releído un par de veces.
    • Bueno, pero ¿cómo es un retorno diferente de un tiro? Si vuelve, a continuación, el bloque debe regresar, pero en un bloque finally, el retorno será pospuesto y hay alguna extraña excepción para el retorno, por lo que no está claro que finalmente controla tirar de una manera normal. Esa es la principal razón por la que escribí este entonces. También lanzar en un bloque try o catch no obstaculizar el bloque finally de la ejecución, por lo ofc. uno podría esperar que cuando se lanza en un bloque finally se sigue ejecutando.
    • «¿cómo es diferente de tiro?» En un par de maneras, ninguno de los cuales son relevantes aquí. En un bloque finally, el retorno no es aplazada, o ¿te refieres a los de retorno en la prueba de bloque posponerse hasta después de fin de bloque se ejecuta (en cuyo caso, sí que es cierto)? De cualquier manera, lo mismo vale para lanzada excepciones. No importa lo que sucede en un try, cuando el final de try es alcanzado, el control pasa a finally, entonces todos las mismas reglas se aplican dentro de la finally (con cualquier try/catch dentro de finalmente operativos, como usualmente lo haría).
    • No estoy diciendo que su respuesta es incorrecta o inútiles, o algo como eso. Es técnicamente correcta. Yo simplemente observar que el comportamiento que usted describe no es nada que rompe el try/finally regla de que «No importa lo que sucede en try/catch, una vez que han terminado de control de flujo será pasar al bloque finally» El try/finally garantía es esencialmente nada más y nada menos que eso. Dentro de cualquier bloque, sea try/catch/finally o de lo contrario, puede que dentro de ella nido de otro try/catch/finally bloques como usted sugiere. De hecho, algunas personas no son conscientes de que.
  43. 2

    bloque finally siempre se ejecuta incluso si usted pone una instrucción return en el bloque try. El bloque finally se ejecutará antes de la instrucción return.

  44. 2

    Finalmente siempre se llama al final

    cuando se intenta, se ejecuta el código, si algo sucede en tratar, a continuación, captura se captura la excepción y se puede imprimir algunos mssg o tirar un error, entonces el bloque finally se ejecuta.

    Finalmente se utiliza normalmente cuando se hace la limpieza, por ejemplo, si utiliza un escáner en java, usted probablemente debería cerrar el escáner, ya que conduce a otros problemas tales como no ser capaz de abrir algún archivo

  45. 0

    Aquí hay algunas condiciones que se pueden omitir un bloque finally:

    1. Si la JVM salidas, mientras que el try o catch código se está ejecutando, entonces, el bloque finally no se puede ejecutar. Más sobre sol tutorial
    2. Apagado Normal – esto ocurre cuando el último no-demonio subproceso salidas O cuando el tiempo de ejecución.exit() (algún buen blog). Cuando un subproceso salidas, la JVM se realiza un inventario de procesos en ejecución, y si la única subprocesos que están a la izquierda son de demonio de hilos, se inicia un apagado ordenado. Cuando la JVM se detiene, los restantes demonio de hilos son abandonados por último los bloques no son ejecutadas, las pilas no se desenrolla el JVM acaba de salidas. Demonio de hilos debe ser usado con moderación algunas de las actividades de procesamiento puede ser de forma segura abandonado en cualquier momento y sin limpieza. En particular, es peligroso utilizar demonio de hilos para las tareas que podría realizar cualquier tipo de I/O. Demonio de hilos son mejor guardado para la «limpieza» de las tareas, tales como un subproceso de fondo que de forma periódica elimina las entradas caducadas de una caché en memoria (fuente)

    Última no-demonio hilo sale de ejemplo:

    public class TestDaemon {
        private static Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        System.out.println("Is alive");
                        Thread.sleep(10);
                        //throw new RuntimeException();
                    }
                } catch (Throwable t) {
                    t.printStackTrace();
                } finally {
                    System.out.println("This will never be executed.");
                }
            }
        };
    
        public static void main(String[] args) throws InterruptedException {
            Thread daemon = new Thread(runnable);
            daemon.setDaemon(true);
            daemon.start();
            Thread.sleep(100);
            //daemon.stop();
            System.out.println("Last non-daemon thread exits.");
        }
    }

    De salida:

    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive
    Last non-daemon thread exits.
    Is alive
    Is alive
    Is alive
    Is alive
    Is alive

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea