在编译级别1.4时jvm编译try/catch/finally块的方式

28 篇文章 0 订阅

        先上一段很简单,且不考虑健壮性的源码:

import java.io.FileInputStream;
import java.io.IOException;
public class TryCatchFinallyTest {
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		FileInputStream fips = null;
		try {
			fips = new FileInputStream("hello.txt");
			fips.read();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			fips.close();
		}
	}
}

         然后上一段这段代码在eclipse编译级别为1.4、没有inline finally块时编译出的字节码:

// Compiled from TryCatchFinallyTest.java (version 1.2 : 46.0, super bit)
public class TryCatchFinallyTest {
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public TryCatchFinallyTest();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 6]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: TryCatchFinallyTest
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 3, Locals: 5
  public static void main(java.lang.String[] args) throws java.io.IOException;
     0  aconst_null
     1  astore_1 [fips]
     2  new java.io.FileInputStream [19]
     5  dup
     6  ldc <String "hello.txt"> [21]
     8  invokespecial java.io.FileInputStream(java.lang.String) [23]
    11  astore_1 [fips]
    12  aload_1 [fips]
    13  invokevirtual java.io.FileInputStream.read() : int [26]
    16  pop
    17  goto 43
    20  astore_2 [e]
    21  aload_2 [e]
    22  invokevirtual java.io.IOException.printStackTrace() : void [30]
    25  goto 43
    28  astore 4
    30  jsr 36
    33  aload 4
    35  athrow
    36  astore_3
    37  aload_1 [fips]
    38  invokevirtual java.io.FileInputStream.close() : void [33]
    41  ret 3
    43  jsr 36
    46  return
      Exception Table:
        [pc: 2, pc: 17] -> 20 when : java.io.IOException
        [pc: 2, pc: 25] -> 28 when : any
        [pc: 43, pc: 46] -> 28 when : any
      Line numbers:
        ......
      Local variable table:
        [pc: 0, pc: 47] local: args index: 0 type: java.lang.String[]
        [pc: 2, pc: 47] local: fips index: 1 type: java.io.FileInputStream
        [pc: 21, pc: 25] local: e index: 2 type: java.io.IOException
}

         2-17是try块代码;

           20-25是catch块代码;

           28-35是编译期生产的catch块之外的异常即any类型异常要执行的代码;

           36-41是finally块代码;

           43-46是编译期生成的字节码;

           其中偏移量17和25处都是goto 43,然后jsr到finally,即try和catch块都是到43;any类型中有一条指令jsr到finally块。

        归纳总结下,try/catch/finally结构中:

        1、try/catch块翻译成指令后最后一条字节码指令都是goto到一个编译出来的块A(43-46),A第一条指令(43)即jsr到finally块第一条指令,finally完就ret到A第二条指令即return(46)

        2、any块,即catch之外的异常类型,也即any,是jvm自己构造了一个指令块B(28-35),先store下这种异常实例到局部变量表(28),然后jsr到finally块中(30),finally完就ret到B的第三条指令(33)执行,load出之前存储到局部变量表的异常实例,然后athrow(35)。

 

        JSR指令后边一般是:

        1、load返回值然后return的指令(try/catch块,有返回值)

        2、直接return(try/catch块,无返回值)

        3、load出异常然后athrow(catch any)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值