0

I have following code :

public class test3    
{
    public static void main(String a[])
    {
        System.out.println("In main");
        System.out.println(new Demo(0).devide());    
    }
}
class Demo
{
    int x;
    Demo(int x)
    {
        this.x=x;
    }
    public int devide()
    {   
        try
        {
            return x/x;
        }
        catch(Exception e)
        {
            System.out.println(e);
            return 4;

        }
        finally
        {
            System.out.println("In finally");
            return 1;
        }    
    }
}

In above code I expect 4 as output but output generated is :

In main
java.lang.ArithmeticException: / by zero
In finally
1

so it returns 1

njzk2
  • 38,969
  • 7
  • 69
  • 107
  • 1
    this is exactly what has been asked in this question: http://stackoverflow.com/questions/15225819/try-catch-finally-return-clarification-in-java – varnie Sep 06 '13 at 07:45
  • 1
    Have a read through this [similar question](http://stackoverflow.com/questions/18480258/finally-block-does-not-set-values-of-variable-in-java/18480305#18480305), it may help – MadProgrammer Sep 06 '13 at 07:46

8 Answers8

2

Finally is always invoked right before exiting the try/catch block, even if the catch returns. In effect, return in finally preceedes the return in catch, and the return in catch never takes place. See here for details and explanation.

Basically, it boils down to the way it's translated to bytecode. Code in finally is treated as a "subprocedure", and at each exit point, right before leaving the try/catch block, a jsr jump is executed to the code in finally. As the subprocedure jump is not a real procedure call, return in finally inhibits the return from subprocedure to the point from which it was entered, and so the original return is never executed.

Rough translation of divide() to bytecode could look like this:

    aload_0
    getfield   // x
    dup
    idiv
    istore_1
    jsr        // to finally block
    iload_1
    ireturn

// catch
    bipush 4
    istore_1
    jsr        // to finally block
    iload_1
    ireturn

// finally
    astore_2   // save the return address
    bipush 1
    ireturn
    ret 2      // dead code

There we can see clearly why is the return in catch never executed.

Marcin Łoś
  • 3,226
  • 1
  • 19
  • 21
2
finally
{

}

will be executed at last no matter what other code is executed before or not

So, at last it will return you 1, which actually you didn't expect :)

Parth Soni
  • 11,158
  • 4
  • 32
  • 54
2

what happens is the following:

  1. code reaches return 4;
  2. value 4 is put on the return stack
  3. code reaches return 1;
  4. value 1 is put on the return stack
  5. method ends, top of the stack is returned (thus value 1) and value 4 is discarded.
Claudiu
  • 1,469
  • 13
  • 21
1
In above code I expect 4 as output but output generated is :
In main
java.lang.ArithmeticException: / by zero
In finally
1

What did you expect?

Finally block will always be executed unless JVM crashes or you call System.exit() before. Since you are returning 1 in finally block you will get 1 as the output.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
1

As per JLS 14.20.2. Execution of try-finally and try-catch-finally:

If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:

If the run-time type of V is assignment compatible with a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed. Then there is a choice:

If the catch block completes normally, then the finally block is executed.

Community
  • 1
  • 1
Tadas S
  • 1,955
  • 19
  • 33
1

finally block is always exectued, ALWAYS. Well maybe if you call System.exit(0) in the try it wouldn't be. But in other situations it is - no matter how the try / catch did exit (normally or abruptly).

The return value of finally (if you specify it) OVERWRITES the return from try/catch. Same goes for exceptions - the ones from try/catch get discarded, if finally throws its own exception.

Sir Bohumil
  • 231
  • 1
  • 9
0

In this case 4 is also add to stack but after finally runs this will return 1. So that you can see only 1 since 1 is the top element of the stack.

Check this out

 try
    {
        return x/x;
    }
    catch(Exception e)
    {
        System.out.println(e);
        x=4;
        return x++;


    }
    finally
    {
        System.out.println("In finally");
        return x;
    }

What you can see

    In main
    java.lang.ArithmeticException: / by zero
    In finally
    5

now you can realize both catch and finally return the value, but we can see the top element in the stack.

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
0

Finally block is executed if your program execution control is entered into the try block.No mater whether try block will execute without any exception or any exception or in try block you are using return statement JVM will always execute finally block before terminating your program. Ex:

 public class test3    
{
    public static void main(String a[])
    {
        System.out.println("In main");
        System.out.println(new Demo(10).devide());    
    }
}
class Demo
{
    int x;
    Demo(int x)
    {
        this.x=x;
    }
    public int devide()
    {   
        try
        {
            return x/x;
        }
        catch(Exception e)
        {
            System.out.println(e);
            return 4;

        }
        finally
        {
            System.out.println("In finally");
            return 1;
        }    
    }
}

Above pgm will execute without any exception but still finally block will execute.

Jayant Jadhav
  • 318
  • 4
  • 12