[讨论] 关于try-finally编译
miroku
2013-06-21
最近在看JLS中关于try-cache-finally的编译,有一些问题不明白,请各位大神指点,代码如下:
public class TestReturn { /** * @param args */ public static void main(String[] args) { TestReturn obj = new TestReturn(); System.out.println(obj.get()); } public String get(){ String ret = ""; try{ ret = "aa"; return ret; }finally{ ret = "bb"; } } } javac后的字节码如下,只贴出了get()方法的 public java.lang.String get(); flags: ACC_PUBLIC Code: stack=1, locals=4, args_size=1 0: ldc #36 // String aa 2: astore_1 3: aload_1 4: astore_3 5: ldc #38 // String bb 7: astore_1 8: aload_3 9: areturn 10: astore_2 11: ldc #38 // String bb 13: astore_1 14: aload_2 15: athrow Exception table: from to target type 3 5 10 any LineNumberTable: line 14: 0 line 16: 3 line 18: 5 line 16: 8 line 17: 10 line 18: 11 line 20: 14 LocalVariableTable: Start Length Slot Name Signature 0 16 0 this Lcpm/soso/quan/TestReturn; 3 13 1 ret Ljava/lang/String; StackMapTable: number_of_entries = 1 frame_type = 255 /* full_frame */ offset_delta = 10 locals = [ class cpm/soso/quan/TestReturn, class java/lang/String ] stack = [ class java/lang/Throwable ] 这里有几个疑问: 1、首先上面代码打印的是 aa 2、编译后第4行字节码多了我java代码没有定义的局部变量,java代码中只有2个,但是编译后却有4个 请各位大神指点 |
|
RednaxelaFX
2013-06-21
直接在finally里用return语句可以干涉返回值,但只是改变显式的局部变量则不改变返回值。finally在执行时,语义上说那个try块里的return语句已经执行完了,只是控制流临返回之前进入finally块里转一圈而已。因而这个例子在实际javac实现中,try块里的return语句要返回的值被缓存在了一个编译器生成的局部变量里(slot 3),等实际返回的时候再拿出来。
slot 2则被用于临时存放try块里可能抛出的异常,用于在finally末尾重新抛出。 |
|
miroku
2013-06-22
RednaxelaFX 写道 直接在finally里用return语句可以干涉返回值,但只是改变显式的局部变量则不改变返回值。finally在执行时,语义上说那个try块里的return语句已经执行完了,只是控制流临返回之前进入finally块里转一圈而已。因而这个例子在实际javac实现中,try块里的return语句要返回的值被缓存在了一个编译器生成的局部变量里(slot 3),等实际返回的时候再拿出来。
slot 2则被用于临时存放try块里可能抛出的异常,用于在finally末尾重新抛出。 这个是JLS要求的么?我在JLS7里没看到相应的说明,还是说这个只是hotspot的一个实现? |
|
RednaxelaFX
2013-06-22
miroku 写道 RednaxelaFX 写道 [color=red]直接在finally里用return语句可以干涉返回值,但只是改变显式的局部变量则不改变返回值。finally在执行时,语义上说那个try块里的return语句已经执行完了,只是控制流临返回之前进入finally块里转一圈而已。[/url]因而这个例子在实际javac实现中,try块里的return语句要返回的值被缓存在了一个编译器生成的局部变量里(slot 3),等实际返回的时候再拿出来。
slot 2则被用于临时存放try块里可能抛出的异常,用于在finally末尾重新抛出。 这个是JLS要求的么?我在JLS7里没看到相应的说明,还是说这个只是hotspot的一个实现? 标红的地方是JLS规定的,其它是Oracle/Sun JDK里的javac的实现细节。跟HotSpot VM没关系。 |
相关讨论
相关资源推荐
- try-catch-finally执行顺序验证
- try-catch-finally 和 try-with-resources
- Java异常try-catch-finally和try-with-resources
- try-catch-finally return 的执行顺序
- 详述try-catch-finally
- java中异常处理之try-catch-finally
- python—try-expect-else-finally的使用
- 关于try-catch-finally-return的执行顺序的一些总结
- 异常处理机制一:try-catch-finally
- 简述try-catch-finally异常捕获