接上一部份:
以下是一个简单的异常处理例子:
public class ExFun { public static void main(String[] args) { try { System.out.println("In try block"); throw new Exception(); } catch (java.io.IOException ioEx) { System.out.println("In catch IOException block"); System.out.println(ioEx); } catch (Exception ex) { System.out.println("In catch Exception block"); System.out.println(ex); } finally { System.out.println("In finally block"); } } } 字节码为:
Compiled from "ExFun.java" public class ExFun extends java.lang.Object SourceFile: "ExFun.java" minor version: 0 major version: 50 Constant pool: (snipped for simplicity) { public ExFun(); (snipped for simplicity) public static void main(java.lang.String[]); Code: Stack=2, Locals=3, Args_size=1 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String In try block 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: new #5; //class java/lang/Exception 11: dup 12: invokespecial #6; //Method java/lang/Exception."<init>":()V 15: athrow 16: astore_1 17: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 20: ldc #8; //String In catch IOException block 22: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 25: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 28: aload_1 29: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 32: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 35: ldc #10; //String In finally block 37: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: goto 81 43: astore_1 44: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 47: ldc #11; //String In catch Exception block 49: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 52: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 55: aload_1 56: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 59: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 62: ldc #10; //String In finally block 64: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 67: goto 81 70: astore_2 71: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 74: ldc #10; //String In finally block 76: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 79: aload_2 80: athrow 81: return Exception table: from to target type 0 16 16 Class java/io/IOException 0 16 43 Class java/lang/Exception 0 32 70 any 43 59 70 any 70 71 70 any LineNumberTable: (snipped) StackMapTable: (snipped) } “try”块内的操作符是在0~16的范围内,Java源代码的“catch”块是被编在异常(Exception)表的开始两行(0(来自)~16(目标)~16(类型) java.io.IOException,0~6~43 java.lang.Exception),catch的操作符偏移量分别是16和43。也需要注意的是,异常表的最后三行表明了方法的其他地方抛出异常的情况(在异常块内部也一样),必须跳转到操作符70处来进行finally块的处理。而且需要注意的是,每个catch块都会对应一个finally块,所以finally块在字节码中重复出现了两次。这只是一个简单的例子,让我们看见了javac编译产生的字节码输出。
|
|