使用javap分析finally块和return值

使用javap分析finally块和return

 

标题: 使用javap分析finally块中return

作者: pwsource

邮箱: pwsource@gmail.com

 

目录:

1.使用javap反编译字节码分析原因。 啥也甭说,看源码注释

2. 源代码

 


 

正文:

 

1. 使用javap反编译字节码分析原因。

 

 

E:/>javap -c -classpath E:/workspace/myTest/bin test.Test

E:/>javap -c -classpath E:/workspace/myTest/bin test.Test

Compiled from "Test.java"

public class test.Test extends java.lang.Object{

public test.Test();

  Code:

   0:   aload_0

   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V

   4:   return

 

public static int testInt();

  Code:

   0:   iconst_0

   1:   istore_0        //x=0 ,保存在本地变量store[0]

   2:   iconst_1

   3:   istore_0        //x=1

   4:   iload_0         //获取store[0]x=1)的值

   5:   istore_3        // store[0]x=1 转存在本地变量store[3]

   6:   jsr     17      // 跳转到finally

   9:   iload_3         // 获取store[3]的值x=1

   10:  ireturn         //返回x=1

   11:  astore_2

   12:  jsr     17

   15:  aload_2

   16:  athrow

   17:  astore_1       //finally

   18:  iconst_2       //相对于testRef()此处不需要再次load变量,因为code4 已将数据加载到栈顶了。

   19:  istore_0       //x赋值2,将x的值保存在本地变量store[0]

   20:  ret     1       //返回到代码【6:   jsr     17

  Exception table:

   from   to  target type

     2     9    11   any

 

public static test.Test$Ref testRef();

  Code:

   0:   new     #20; //class test/Test$Ref               //创建Ref实例

   3:   dup                                                   //拷贝Ref实例到栈顶

   4:   aconst_null

   5:   invokespecial   #22; //Method test/Test$Ref."<init>":(Ltest/Test$Ref;)V          //初始化 Ref.x=null

   8:   astore_0                                             //Ref实例的引用ref保存在 store[0]

   9:   aload_0

   10:  iconst_1

   11:  invokestatic    #25; //Method test/Test$Ref.access$1:(Ltest/Test$Ref;I)V        //赋值Ref.x=1

   14:  aload_0                // store[0]加载Ref实例的引用ref

   15:  astore_3               // 保存Ref实例的引用refstore[3]

   16:  jsr     27              // jump to finally

   19:  aload_3                // store[3]中加载Ref实例的引用ref,实例的值ref.x已经变为2

   20:  areturn                // 返回Ref.x=2

   21:  astore_2

   22:  jsr     27

   25:  aload_2

   26:  athrow

   27:  astore_1               // finally

   28:  aload_0                // store[0]加载Ref实例的应用

   29:  iconst_2

   30:  invokestatic    #25; //Method test/Test$Ref.access$1:(Ltest/Test$Ref;I)V     //通过实例的引用ref修改x的值, Ref.x=2

 

   33:  ret     1     //返回到代码【16:  jsr     27

  Exception table:

   from   to  target type

     9    19    21   any

 

public static java.lang.String testArr();

  Code:

   0:   iconst_1                                                             //数组大小为1

   1:   anewarray       #33; //class java/lang/String                  //创建数组对象

   4:   dup                             //复制数组的引用x到栈顶

   5:   iconst_0                       //数组x的索引0

   6:   ldc     #35; //String 0

   8:   aastore                        //将字符串”0”的引用存入数组x[0]的位置 注意,数组保存的是对象的引用。

   9:   astore_0                       //将数组的应用x保存在store[0]

   10:  aload_0                        //store[0]加载数组x的引用到栈顶

   11:  iconst_0                       //数组x的索引0

   12:  ldc     #37; //String 1      

   14:  aastore                        //将字符串”1”的引用存入数组x[0]的位置

   15:  aload_0                        //store[0]加载数组x的引用到栈顶

   16:  iconst_0                       //数组x的索引0

   17:  aaload                         //加载x[0]x[0]保存的是字符串”1”的索引

   18:  astore_3                       //x[0]字符串”1”的索引)保存在store[3]

   19:  jsr     30                     // jump to finally

   22:  aload_3                        //store[3]加载x[0], x[0]=”1”

   23:  areturn                        // 返回x[0]=”1”

   24:  astore_2

   25:  jsr     30

   28:  aload_2

   29:  athrow

   30:  astore_1

   31:  aload_0                        //store[0]加载数组x的引用到栈顶

   32:  iconst_0                       //数组x的索引0

   33:  ldc     #39; //String 2

   35:  aastore                        //将字符串”2”的引用存入数组x[0]的位置

   36:  ret     1


 

  Exception table:

   from   to  target type

    10    22    24   any

 

public static void main(java.lang.String[]);

  Code:

   0:   getstatic       #44; //Field java/lang/System.out:Ljava/io/PrintStream;

   3:   new     #50; //class java/lang/StringBuffer

   6:   dup

   7:   ldc     #52; //String x=?

   9:   invokespecial   #54; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V

   12:  invokestatic    #57; //Method testInt:()I

   15:  invokevirtual   #59; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;

   18:  invokevirtual   #63; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;

   21:  invokevirtual   #66; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

   24:  getstatic       #44; //Field java/lang/System.out:Ljava/io/PrintStream;

   27:  new     #50; //class java/lang/StringBuffer

   30:  dup

   31:  ldc     #52; //String x=?

   33:  invokespecial   #54; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V

   36:  invokestatic    #71; //Method testRef:()Ltest/Test$Ref;

   39:  invokevirtual   #73; //Method java/lang/StringBuffer.append:(Ljava/lang/Object;)Ljava/lang/StringBuffer;

   42:  invokevirtual   #63; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;

   45:  invokevirtual   #66; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

   48:  getstatic       #44; //Field java/lang/System.out:Ljava/io/PrintStream;

   51:  new     #50; //class java/lang/StringBuffer

   54:  dup

   55:  ldc     #52; //String x=?

   57:  invokespecial   #54; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V

   60:  invokestatic    #76; //Method testArr:()Ljava/lang/String;

   63:  invokevirtual   #78; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;

   66:  invokevirtual   #63; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;

   69:  invokevirtual   #66; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

   72:  return

}

 

 

2. 源代码

  

 

运行结果:

x=? 1

x=? 2

x=? 1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值