return como - ¿Un bloque finalmente se ejecuta siempre en Java?




clause funciona (25)

Sí, finalmente el bloque siempre se ejecuta. La mayoría de los desarrolladores utilizan este bloque para cerrar la conexión de la base de datos, el objeto del conjunto de resultados, el objeto de declaración y también los utilizan en la hibernación de Java para revertir la transacción.

Teniendo en cuenta este código, ¿puedo estar absolutamente seguro de que el bloque finally siempre se ejecuta, sin importar qué es something() ?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("i don't know if this will get printed out.");
}

Una manera lógica de pensar en esto es:

El código colocado en un bloque finally debe ejecutarse lo que ocurra dentro del bloque try.

Entonces, si el código en el bloque try intenta devolver un valor o lanzar una excepción, el elemento se coloca 'en el estante' hasta que el bloque finally pueda ejecutarse. Debido a que el código en el bloque finally tiene (por definición) una prioridad alta, puede devolver o lanzar lo que le guste En cuyo caso, todo lo que quede "en el estante" se desecha.

La única excepción a esto es si la VM se apaga completamente durante el bloque de prueba, por ejemplo, por 'System.exit'

Nunca lanzar ninguna excepción desde el bloque finalmente

try {
  someMethod();  //Throws exceptionOne
} finally {
  cleanUp();    //If finally also threw any exception the exceptionOne will be lost forever
}

Esto está bien, siempre que cleanUp () nunca pueda lanzar ninguna excepción. En el ejemplo anterior, si someMethod () lanza una excepción, y también en el bloque finally, cleanUp () lanza una excepción, esa segunda excepción saldrá del método y la primera excepción original (razón correcta) se perderá para siempre. Si el código que llama en un bloque finally puede lanzar una excepción, asegúrese de que lo maneja o lo registra. Nunca dejes que salga del bloque finalmente.

En realidad, al salir del programa (ya sea llamando a System.exit () o causando un error fatal que causa que el proceso se interrumpa: algunas veces se hace referencia informalmente como un "punto de acceso" o "Dr Watson" en Windows) evitará que finalmente se bloquee ¡ejecutado!

No hay nada que nos impida anidar los bloqueos try / catch / finally (por ejemplo, poner un bloque try / finally dentro de un bloque try / catch, o viceversa), y no es algo tan inusual.


Código de ejemplo:

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.");
    }
}

Salida:

finally trumps return. 
0

Además, aunque es una mala práctica, si hay una declaración de retorno dentro del bloque finally, prevalecerá sobre cualquier otro retorno del bloque regular. Es decir, el siguiente bloque devolvería falso:

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

Lo mismo con lanzar excepciones del bloque finalmente.


Finalmente, el bloque siempre se ejecuta, ya sea que se trate de excepciones o no. Si se produjo alguna excepción antes del bloque de prueba, el bloque finalmente no se ejecutará.


Considere esto en un curso normal de ejecución (es decir, sin que se lance ninguna excepción): si el método no es 'vacío', entonces siempre devuelve algo explícitamente, sin embargo, finalmente, siempre se ejecuta


Sí se llamará. Ese es el punto central de tener una palabra clave finalmente. Si saltarse fuera del bloque try / catch podría saltar el bloque final, sería lo mismo que poner System.out.println fuera del try / catch.


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

Una sentencia de try con un bloque finally se ejecuta ejecutando primero el bloque de try . Entonces hay una opción:

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

La especificación para return realmente hace esto explícito:

JLS 14.17 La declaración de retorno

ReturnStatement:
     return Expression(opt) ;

Una declaración de return sin Expression intenta transferir el control al invocador del método o constructor que lo contiene.

Una declaración de return con una Expression intenta transferir el control al invocador del método que lo contiene; El valor de la Expression convierte en el valor de la invocación del método.

Las descripciones anteriores dicen " intentos de transferir el control " en lugar de solo " transferencias de control " porque si hay alguna instrucción de try dentro del método o constructor cuyos bloques de try contienen la instrucción de return , entonces se ejecutarán las cláusulas finally de esas declaraciones de try , en Orden, de lo más interno a lo más externo, antes de transferir el control al invocador del método o constructor. La finalización brusca de una cláusula finally puede interrumpir la transferencia de control iniciada por una declaración de return .



La respuesta es simple, sí.

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");
}

SALIDA:

catch
finally

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:

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

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

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

Mientras que el siguiente método lo lanza:

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

Porque siempre se llamará un bloque finally a menos que llames a System.exit() (o el hilo se cuelgue).


De manera concisa, en la documentación oficial de Java (Haga clic here ), está escrito que:

Si la JVM sale mientras se está ejecutando el código try o catch, entonces el bloque finally puede no ejecutarse. Del mismo modo, si el subproceso que ejecuta el código try o catch se interrumpe o se elimina, el bloque finally puede no ejecutarse aunque la aplicación en su totalidad continúe.


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

Las únicas veces que finally no se llamarán son:

  1. Si System.exit() ;
  2. Si la JVM se bloquea primero;
  3. Si la JVM alcanza un bucle infinito (o alguna otra instrucción no interrumpible, sin terminación) en el bloque try o catch ;
  4. Si el SO termina por la fuerza el proceso de JVM; por ejemplo, "kill -9" en UNIX.
  5. Si el sistema host muere; Por ejemplo, fallo de alimentación, error de hardware, pánico del sistema operativo, etc.
  6. Si finalmente el bloque va a ser ejecutado por el subproceso del daemon y todos los demás subprocesos que no son del demonio, antes de finalmente se llama.

finalmente, siempre se ejecuta a menos que haya una terminación anormal del programa (como llamar a System.exit (0) ..). así, tu sysout se imprimirá


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:

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

Esa es toda la idea de un bloque finalmente. Le permite asegurarse de que realiza limpiezas que, de lo contrario, podrían omitirse porque, por supuesto, entre otras cosas, regresa.

Finalmente, recibe una llamada independientemente de lo que suceda en el bloque de prueba (a menos que llame a System.exit(int) o la Máquina Virtual de Java salga por alguna otra razón).


Porque la final siempre se llama en cualquier caso que tengas. No tiene una excepción, todavía se llama, captura la excepción, todavía se llama


Si lo sera No importa lo que suceda en su bloque try / catch a menos que System.exit () sea llamado o JVM se bloquee. Si hay alguna declaración de devolución en el (los) bloque (es), finalmente se ejecutará antes de esa declaración de devolución.


Finalmente, siempre se ejecuta ese es todo el punto, solo porque aparece en el código después de la devolución no significa que así se implementa. El tiempo de ejecución de Java tiene la responsabilidad de ejecutar este código al salir del bloque try .

Por ejemplo, si tiene lo siguiente:

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

El tiempo de ejecución generará algo como esto:

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

Si se lanza una excepción no detectada, el bloque finally se ejecutará y la excepción continuará propagándose.


Aquí hay una elaboración de la respuesta de Kevin . Es importante saber que la expresión que se devolverá se evalúa antes de finally , incluso si se devuelve 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");
    }
}

Salida:

X
finally trumps return... sort of
0

Si se lanza una excepción, finalmente se ejecuta. Si no se lanza una excepción, finalmente se ejecuta. Si la excepción es atrapada, finalmente se ejecuta. Si la excepción no es atrapada, finalmente se ejecuta.

La única vez que no se ejecuta es cuando sale JVM.


No, no siempre un caso de excepción es // System.exit (0); Antes de que el bloque finalmente impida finalmente 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");
        }
    }
}

Eso es realmente cierto en cualquier idioma ... finalmente, siempre se ejecutará antes de una declaración de devolución, sin importar dónde se encuentre esa devolución en el cuerpo del método. Si ese no fuera el caso, el bloque finalmente no tendría mucho significado.


List<Item> Items = obj.getItems();
for(Item item:Items)
             {
                System.out.println(item); 
             }

Iteriza sobre todos los objetos en la tabla Artículos.







java return try-catch-finally