-1

If the code below is run from an IDE or from the command line, and then stopped either:

  • Stopping its execution from eclipse (red button)
  • Pressing CTRL+C (command line)
  • Naturally (by replacing the while(true) loop by a for loop

never the finally clause is executed ("Finally" never printed out).

public class Test {
    public static void main(String[] args) {
        try {
            while (true) {
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally");
        }
    }
}

Quoting the Java 7 specifications:

If execution of the try block completes normally, then the finally block is executed, and then there is a choice:

Any insights?

EDIT

Oops, my bad, a finite for loop cause the finally clause to be called. I haven't noticed the trace in my unit test. So their is no question now.

Hey StackExchange
  • 2,057
  • 3
  • 19
  • 35
  • 1
    If execution of the try block completes **normally**. I also doubt that your last statement is true (i.e. the for loop completed). – Kayaman Jun 24 '15 at 13:45
  • Is CTRL+C "normal" completion? – vikingsteve Jun 24 '15 at 13:47
  • 4
    You are forcefully stopping the process, that isn't *normally*. Basically what you do is you pull the power plug from the wall socket and you expect your windows desktop client to ask you *are you sure you want to shutdown this computer*... – M. Deinum Jun 24 '15 at 13:48
  • http://stackoverflow.com/questions/65035/does-finally-always-execute-in-java?rq=1 This link will help you. – Nagabhushana G M Jun 24 '15 at 13:48
  • Lol, I read [this](http://www.thedailywtf.com/articles/finally-clear) a few days ago about the "finaly" statement... – Laurent S. Jun 24 '15 at 13:55

7 Answers7

5

the execution never leaves the while loop. If you "red button" the execution it terminates the whole process - so no other code will be able to execute afterwards (unless it is a shutdown hook of the JVM)

light_303
  • 2,101
  • 2
  • 18
  • 35
2
  • Stopping its execution from eclipse (red button)
  • Pressing CTRL+C (command line)

In these cases you terminate the JVM, so the try block does not complete "normally". No JVM, no interpretation of Java bytecode.

  • Naturally (by replacing the while(true) loop by a for loop

Not sure what is happening here. This should work if the for loop is terminable (not an endless-loop). Please post your code.

Puce
  • 37,247
  • 13
  • 80
  • 152
  • I'm assuming he wrote something like for(int i = 0; i > 0; i++) which is exactly the same as while(true) – Manu Jun 24 '15 at 13:53
  • Is that standartized somewhere in JLS? I mean that finally have not to be executed after calling System.exit(0)? –  Jun 24 '15 at 13:57
  • @DmitryBundin AFAIK, yes, it's standartized. I guess in the JLS somewhere. This is one reason you should never call System.exit anywhere except in your main method to set the return value. – Puce Jun 24 '15 at 13:59
2

Correct me if i am wrong, you are saying the finally block isn't getting run when you break out of the program? If so, then you are expecting the wrong behavior from the finally block. The finally will run as the code goes through it's normal course. For instance, when the try has completed (either successfully or with error). You are stopping the program, in which case, nothing else is going forward. The finally is meant to be a part of error handling. Stopping program is not error handling.

rfportilla
  • 310
  • 2
  • 15
0

Finally block will always be executed,except if you call system.exit() through program. This doesn't mean it will be called when you force stop your application which totally shuts down your jvm.

KDP
  • 1,481
  • 7
  • 13
0

By: Stopping its execution from eclipse (red button) Pressing CTRL+C (command line)

You are killing the proccess and nothing is executed after that.

And by replacing the while(true) loop by a for loop this would reach finally.

And the finally block is fired even with Exceptions.

    try{
        for(int i = 0; i < 10; i++);
        throw new RuntimeException("Ex");
    }catch(Throwable e){
        System.out.println("thrown");
    }finally{
        System.out.println("finally");
    }

This will print : thrown finally

Even not caughts exceptions will trigger finally

    try{
        throw new RuntimeException("Ex");
    }finally{
        System.out.println("finally");
    }

this prints finally then the application receive the RuntimeException.

Another way for killing the proccess entirely is by calling System.exit and it will not execute any code further (aka: other code and your finally)

    try{
        System.exit(0);
    }finally{
        System.out.println("finally");
    }

This prints nothing.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
0

What you're doing is terminating the process before it's getting completed.

You can use shutdownhook to handle below scenario:

  • Because all of its threads have completed execution
  • Because of call to System.exit()
  • Because user hit CNTRL-C
  • System level shutdown or User Log-Off

e.g. below

package com.test;

public class Test {
    public static void main(String[] args) {

        Test test = new Test();
        test.attachShutDownHook();
        try {
            while (true) {
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally");
        }
    }

    public void attachShutDownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("Inside Add Shutdown Hook");
            }
        });
        System.out.println("Shut Down Hook Attached.");
    }
}

Finally will get called only if there is exception or program terminates normally.

TheCodingFrog
  • 3,406
  • 3
  • 21
  • 27
0

It's an infinite loop. You should put a break point.

public class Test {
  public static void main(String[] args) {
    try {
        while (true) {
            Thread.sleep(1000);
            break; //Added
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("Finally");
    }
  }
}

Or you can use a flag to set when the loop should ends.

boolean myFlag = true;
while(myFlag) {
    doSomething();
    myFlag = false;
}
Raphael Amoedo
  • 4,233
  • 4
  • 28
  • 37