Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java finally return, and strange bytecode

I saw one Java puzzle problem about finally, and return

    int i = 0;
    try {
        return i;
    } finally {
        i++;
    }

what's return value of this function, I know this will return 0, and I test another code

    StringBuffer sb = new StringBuffer("11");
    try {
        return sb;
    } finally {
        sb.append("22");
    }

it's strange things happend, it return "1122" this's my first question: why it return "1122"?

and I decompile the these two java code,

    0:   iconst_0 put 0 to the stack
1:   istore_0 store the stack top into index 0
2:   iload_0  put index 0 to the stack 
3:   istore_1 store the stack top into index 1
4:   iinc    0, 1 inc the index 0 with 1
7:   iload_1 put index 1 to the stack 
8:   ireturn return the top of stack
// what's the below bytecode mean? because the index 0 has incremented, why increment again?
9:   astore_2
10:  iinc    0, 1
13:  aload_2

this is my second question why 9 - 13 lines byte code means? and the index 0 has incremented, wy increment again?

   0:   new     #2; //class java/lang/StringBuffer
   3:   dup
   4:   ldc     #3; //String 11
   6:   invokespecial   #4; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
   9:   astore_0
   10:  aload_0
   11:  astore_1
   12:  aload_0
   13:  ldc     #5; //String 22
   15:  invokevirtual   #6; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
   18:  pop
   19:  aload_1
   // like the above, this seems should return the value in the index 1, it should be "11"??
   20:  areturn
   21:  astore_2
   22:  aload_0
   23:  ldc     #5; //String 22
   25:  invokevirtual   #6; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
   28:  pop
   29:  aload_2
   30:  athrow

this my third question, it seem the should be the value in the index, it should be "11"??

like image 571
regrecall Avatar asked Jul 28 '26 05:07

regrecall


1 Answers

In the first example, 0 goes on the stack and is returned, regardless of what happens in the finally block.

In the second example, a reference to a StringBuffer goes on the stack, and then the StringBuffer itself is modified in the finally block. But the reference to the StringBuffer is unchanged, and that's what's returned.

like image 59
Dawood ibn Kareem Avatar answered Jul 30 '26 20:07

Dawood ibn Kareem