Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's return value in try-catch-finally mechanism

I have just encountered this following code:

public class TestFinally {
    public static void main(String[] args) {
        int returnValue = function();

        System.out.println("Return value: " + returnValue);
    }

    public static int function() {
        try {
            return 1;
        } catch (Exception e){
            return 2;
        } finally{
            return 3;
        }
    }
}

It is without a doubt that running this code will yield an output of "Return value: 3".

However, I am curious as to:

  1. The mechanism of the innards in the JVM. Does anyone know if the VM actually replaces the return value on the stack by over-writing the first "return 1"? If so, where can I find more information on this.
  2. I have yet to find the use for a return in the finally mechanism that is used this way and allowed in the implemented in the JVM. If this code construct is used as a means to return error code, it is in my opinion there are better ways to log errors or return these error codes. Has anyone found a use for such a construct?

Many thanks in advance.

Cheers, Vern

like image 568
Vern Avatar asked Jan 14 '12 18:01

Vern


People also ask

How do I return a value on try catch?

In a try-catch-finally block that has return statements, only the value from the finally block will be returned. When returning reference types, be aware of any updates being done on them in the finally block that could end up in unwanted results.

What will happen when catch & finally block both return value?

When catch and finally block both return value, method will ultimately return value returned by finally block irrespective of value returned by catch block.

Can we use return statement in try catch or finally block?

Yes, we can write a return statement of the method in catch and finally block.

What happens if I write return in TRY block will finally executes?

Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java. If we call the System.


2 Answers

FWIW, I get a warning on function:

public static int function(){
    try{
        return 1;
    }catch(Exception e){
        return 2;
    }finally{
        return 3; //WARNING on this line
    }
}

Ie. it tells me "finally block does not complete normally". I still get 3 as returned value no matter what.

Anyway, if I try this other example:

public class TestFinally {
    public static void main(String[] args) {
        int returnValue = function();

        System.out.println("Return value: " + returnValue);
    }

    public static int function() {
        try {  

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

the output will be (obviously)

i don't know if this will get printed out.
Return value: 1

I have no idea how the JVM implements it, but the simplest way to look at it (at least conceptually) would be:

  1. the return value in the "try" is pushed onto the stack,
  2. then the "finally" block is executed,
  3. the new return value is pushed onto the stack
  4. the function exits, and the return value is popped from the stack, thus ignoring the first one.

Very neat question indeed.

like image 69
Savino Sguera Avatar answered Oct 17 '22 10:10

Savino Sguera


What I found in the Java language specification at least defines that your code snippet should return 3. Of course, it does not mention how the JVM should implement this, and what possible optimizations one could do.

Section 14.20.2 defines that

If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:

  1. If the finally block completes normally, then the try statement completes abruptly for reason R.
  2. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

And the start of chapter14 (section 14.1 to be more precise) specifies what a normal and abrupt completion is. For example a return with a given value is an abrupt completion.

Hence in this case, the finally block completes abruptly (reason: return with a given value), so the try will complete abruptly for the same reason (and return 3). This is confirmed in section 14.17 about the return statement as well

If evaluation of the Expression completes normally, producing a value V, then the return statement completes abruptly, the reason being a return with value V.

like image 13
Robin Avatar answered Oct 17 '22 10:10

Robin