Do you really know the return in try{return}finally{}?

Source: Internet
Author: User
Tags finally block

Today's visit to the forum found a very interesting question:

Who can give me an explanation of the result of this procedure is: 2. Instead of: 3

The code is as follows:

class Test {public int aaa() {int x = 1;try {return ++x;} catch (Exception e) {} finally {++x;}return x;}public static void main(String[] args) {Test t = new Test();int y = t.aaa();System.out.println(y);}}

After seeing the problem, the following questions were drawn:

    • If you use the return statement in a try statement block, will the finally statement block also execute? (Your answer will not be executed, please be sure to look down ^_^)
    • If so, how do you implement both a return and a finally ? (If your answer is not known, please continue to watch!!) )
    • Why is the above program output 2? (If you don't know, keep looking down ~ ~)
    • On the Internet, people still ask, "Do you want to execute the return first or the finally?" "Of
      (Personally, if you know that finally will execute, you can conclude that the finally is executed first and then the return is executed.) Because, if the return is executed first, then the whole function jumps out, so how do we do finally? ^_^)

Just after seeing this problem. Suddenly found that the foundation is not solid enough, incredibly come to the first to answer not come out ... (I do not know that there are Muyou and I also can not answer the above questions?) If please tell me in the comments, let me know, I am not lonely ~ ~)

Know according to existing knowledge:
return can be used as a terminating statement, and we often use it to jump out of the current method and return a value to the calling method. Then the method ends, and the statement below return is not executed.
finally : Regardless of what happens to the try statement, whether it throws an exception or executes normally. The finally statement will execute.
So here's the problem .... Will the finally be executed after using return in the Try statement? Is the statement that finally will be carried out be established? If so, do the return first or the finally?

Verifies whether the finally statement executes, and the order in which the return and finally are executed

Driven by curiosity, I continued to delve deeper, decisively opening the Oracle home page and flipping through the finally statement of the official Java tutorial. Discover the official tutorials for this particular case:

The finally block always executes when the try block exits. This ensures, the finally block is executed even if an unexpected exception occurs. But finally was useful for more than just exception handling-it allows the programmer to avoid have cleanup code accide Ntally bypassed by a return, continue, or break. Putting cleanup code in a finally block was always a good practice, and even when no exceptions was anticipated.

Note:if the JVM exits while the try or catch code is being executed and then the finally block could not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block could not execute even t Hough the application as a whole continues.

Individual simple translation:

A finally statement is definitely executed when the try statement exits. This ensures that a finally statement block is executed even if an unexpected exception is sent. But finally is not only useful for handling exceptions-it allows programmers to ignore cleanup code because of a return, continue, or break statement. It is a good practice to put the cleanup code in the finally statement block, even if it is not possible to do so in the event of an exception.

Note that when the code for the try or catch is running, the JVM exits. Then the finally statement block is not executed. Similarly, if a thread is interrupted or killed (killed) while running the code for a try or catch, then the finally statement may not be executed, even if the entire application continues to execute.

From the official note above, we know that the finally statement block will continue to execute regardless of whether a return statement, break statement, or continue statement is executed in the try . At the same time, an answer has been found in StackOverflow, and we can call System.exit () to terminate it:

Finally'll be called.
The only time finally won ' t is called Is:if you call System.exit (), another thread interrupts current one, or if the JVM Crashes first.

In addition, in the Java language Specification, if there is a return statement in the Try statement, the finally statement will still be executed. It executes the finally statement before transferring control to the caller or constructor of the method. That is, a finally statement is executed before the return statement is used to transfer control to another method.

Personal verification

We still use the code above as an example. First, add breakpoints in front of the following three lines of code, respectively:

    • int x = 1;
    • return ++x;
    • ++x;

Then run the code in debug mode.

At first, the effect is as follows:

Click F6, we can find that the program has been executed to return ++x, but has not executed the statement, the moment X=1

Continue to click F6, the program executes to ++x, but the statement is not executed, so the x=2 at this point (the ++x of the return ++X statement has just been executed, but no return is executed)

Continue to press F6, at this point, we find that the program jumps back to return +xx This line, the moment x=3 (executed the ++x in the finally statement)

As you can see from the above process,

    • Use return in a try or execute a finally statement (we see in debug mode that the program executes in the conditional finally statement)
    • Execution of the finally statement does not execute return. Why? From the above figure can reasonably infer the return +XX, is executed separately, executes the ++x first, then executes finally, finally executes the return to jump out the function. Because the program two times jump to return +xx; Statement. (In fact, to verify that the return ++x is a separate two-part execution of the method is very simple, the variable x into a static variable and output in the main function, you will find the value of X or 3, even if two times jump to return ++x It is only the first time that the add 1 operation was performed, and the second time just executed the return without executing the ++x. Here is reasonable reasoning, behind the proof ~ ~)

Seeing this, we might get tangled up again. As you can see from the above verification, the finally statement executes, and the value of x does add up to 3, so why is y 2?

Verify why 2 is not 3

Turning to the official JVM specification will unravel all the mysteries:

If the TRY clause executes a return, the compiled code does the following:

  1. Saves The return value (if any) in a local variable.
  2. Executes a JSR to the code for the finally clause.
  3. Upon return from the finally clause, returns the value saved in the local variable.

Under Simple translation:

If there is a return in the Try statement, then the code behaves as follows:
1. If there is a return value, save the return value to the local variable
2. Perform a JSR instruction jump to the finally statement
3. After executing the FINALLY statement, return the value saved in the local variable table

According to the above instructions, it is easy to explain why it is 2.
When executed to return ++x, the JVM allocates another space in the local variable table to hold the value of the current x when the ++x is executed.
Notice that the value is not returned to Y yet, but continues to execute the statement in the finally statement. When the execution is finished, the previously saved value (2 is not X) is returned to Y.
So there's a case where Y is 2, not 3.

In fact, it is also important to note that if you also use the return statement in finally, such as return +XX. Then Y will be 3. Because the specification specifies that when both try and finally have a return, the return of the try is ignored and the return of finally is used.

View Test.class bytecode We can also easily know why it is 2 instead of 3:

About the order of instruction Operation:
Iconst_1: Put the constant 1 into the stack---> istore_1: Stack top element out of the stack and save the element in the local variable table in the second position (subscript 1 in the position)---> Iinc 1, 1: The second element of the local variable table is increased by 1--->iload_1: The second element in the stack---> istore_2: Stack top element out of the stack and save the element in the 2nd position of the local variable table---> Iinc 1, 1: The second element of the local variable table is 1---> iload_2: The second element is in the stack (note that at this point the top element of the stack is 2)---> Ireturn: Returns the top element of the stack.

The following instruction is to jump to 12 rows when an exception occurs in 2-7 rows, this example does not appear abnormal, do not pay attention.

The above process stack and local variable table are as follows:

Summarize
    • Once again discover the benefits of helping others to solve problems, not only to help people can also improve their own
    • The knowledge of bytecode is quite practical, and we have to study it in depth.
    • It's really useful to prove the official tutorials and materials again.
    • This article transferred from: http://www.cnblogs.com/averey/p/4379646.html

Do you really know the return in try{return}finally{}?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.