Does a finally block always get executed in Java?

前端 未结 30 1579
逝去的感伤
逝去的感伤 2020-11-21 07:24

Considering this code, can I be absolutely sure that the finally block always executes, no matter what something() is?

try         


        
相关标签:
30条回答
  • 2020-11-21 07:28

    Here's the official words from the Java Language Specification.

    14.20.2. Execution of try-finally and try-catch-finally

    A try statement with a finally block is executed by first executing the try block. Then there is a choice:

    • If execution of the try block completes normally, [...]
    • If execution of the try block completes abruptly because of a throw of a value V, [...]
    • If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
      • If the finally block completes normally, then the try statement completes abruptly for reason R.
      • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

    The specification for return actually makes this explicit:

    JLS 14.17 The return Statement

    ReturnStatement:
         return Expression(opt) ;
    

    A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it.

    A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation.

    The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.

    0 讨论(0)
  • 2020-11-21 07:32

    The finally block is always executed unless there is abnormal program termination, either resulting from a JVM crash or from a call to System.exit(0).

    On top of that, any value returned from within the finally block will override the value returned prior to execution of the finally block, so be careful of checking all exit points when using try finally.

    0 讨论(0)
  • 2020-11-21 07:32

    Yes it will get called. That's the whole point of having a finally keyword. If jumping out of the try/catch block could just skip the finally block it was the same as putting the System.out.println outside the try/catch.

    0 讨论(0)
  • NOT ALWAYS

    The Java Language specification describes how try-catch-finally and try-catch blocks work at 14.20.2
    In no place it specifies that the finally block is always executed. But for all cases in which the try-catch-finally and try-finally blocks complete it does specify that before completion finally must be executed.

    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).
    

    The JLS does not guarantee that FIN is executed after CODE. The JLS guarantees that if CODE and NEXT are executed then FIN will always be executed after CODE and before NEXT.

    Why doesn't the JLS guarantee that the finally block is always executed after the try block? Because it is impossible. It is unlikely but possible that the JVM will be aborted (kill, crash, power off) just after completing the try block but before execution of the finally block. There is nothing the JLS can do to avoid this.

    Thus, any software which for their proper behaviour depends on finally blocks always being executed after their try blocks complete are bugged.

    return instructions in the try block are irrelevant to this issue. If execution reaches code after the try-catch-finally it is guaranteed that the finally block will have been executed before, with or without return instructions inside the try block.

    0 讨论(0)
  • 2020-11-21 07:35

    No, not always one exception case is// System.exit(0); before the finally block prevents finally to be executed.

      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");
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:35

    Answer is simple YES.

    INPUT:

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

    OUTPUT:

    catch
    finally
    
    0 讨论(0)
提交回复
热议问题