Java终于返回了,奇怪的字节码

时间:2014-04-05 03:54:55

标签: java jvm return java-bytecode-asm try-catch-finally

我终于看到了一个Java难题,然后返回

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

这个函数的返回值是什么,我知道这将返回0,我测试另一个代码

    StringBuffer sb = new StringBuffer("11");
    try {
        return sb;
    } finally {
        sb.append("22");
    }
发生了奇怪的事情,它回归" 1122" 这是我的第一个问题:为什么它会回归" 1122"?

我反编译了这两个java代码,

    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

这是我的第二个问题为什么9 - 13行字节代码意味着什么?并且索引0已经递增,再次增加?

   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

这是我的第三个问题,似乎应该是索引中的值,它应该是&#34; 11&#34; ??

2 个答案:

答案 0 :(得分:6)

在第一个示例中,无论finally块中发生了什么,0都会返回堆栈并返回。

在第二个示例中,对StringBuffer的引用进入堆栈,然后在StringBuffer块中修改finally本身。但是对StringBuffer的引用没有改变,这就是返回的内容。

答案 1 :(得分:4)

可以在不查看字节码的情况下解释代码的行为和第一个问题:

代码返回 StringBuffer对象。该对象是可变的,它在finally块中 mutated ,它在执行返回给调用者之前运行。 (它仍然返回相同的 StringBuffer对象。)

尝试return sb.toString()(并更改返回类型以匹配) - 在这种情况下,StringBuffer的副作用不会影响返回的字符串对象。

(我不知道实际字节码的问题。)