error handling - Does a finally block always get executed in Java?

ID : 276

viewed : 154

Tags : javaerror-handlingreturntry-catch-finallyjava

Top 5 Answer for error handling - Does a finally block always get executed in Java?

vote vote

95

Yes, finally will be called after the execution of the try or catch code blocks.

The only times finally won't be called are:

  1. If you invoke System.exit()
  2. If you invoke Runtime.getRuntime().halt(exitStatus)
  3. If the JVM crashes first
  4. If the JVM reaches an infinite loop (or some other non-interruptable, non-terminating statement) in the try or catch block
  5. If the OS forcibly terminates the JVM process; e.g., kill -9 <pid> on UNIX
  6. If the host system dies; e.g., power failure, hardware error, OS panic, et cetera
  7. If the finally block is going to be executed by a daemon thread and all other non-daemon threads exit before finally is called
vote vote

89

Example code:

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

Output:

something is printed.  0 
vote vote

71

Also, although it's bad practice, if there is a return statement within the finally block, it will trump any other return from the regular block. That is, the following block would return false:

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

Same thing with throwing exceptions from the finally block.

vote vote

60

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.

vote vote

58

In addition to the other responses, it is important to point out that 'finally' has the right to override any exception/returned value by the try..catch block. For example, the following code returns 12:

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

Similarly, the following method does not throw an exception:

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

While the following method does throw it:

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

Top 3 video Explaining error handling - Does a finally block always get executed in Java?

Related QUESTION?