CSDN博客

img qlampskyface

用i=i++ + ++i带你入门javap

发表于2004/7/13 14:27:00  1239人阅读

分类: J2SE

关键字:java   javap
和作者联系:xiaozuidaizhi@sina.com
============================================================================================
 摘要: javap是一个很好的深入查看程序内部运行机制的工具,不过它有不同于汇编的自有格式的语句。本文
通过用javap对i=i++ + ++i 这一特殊语言现象进行分析,带你进入javap的微观世界。
============================================================================================
        首先我们来了解一下javap命令及其基本用法。
javap是sun提供的对class文件进行反编译的工具,javap和javac、java等bin文件存放路径相同,当你配置好了环
境变量后,javap就和javac、java等命令的用法类似了。
        javap最基本的用法,也是最常用的用法如下:
        javap -[参数] test
        其中,test是test.java文件经javac编译后产生的class文件名,也就是说,在javap之前,你必须用javac编译这
个文件,需要注意的一点是,在使用javap反编译.class文件时,不要带上其后缀名,否则会报错。
        我们对javap最常用的参数是c,也就是形如
javap -c test  的用法,如果你还想对javap的参数进一步了解的话,
我向你推荐
www.javaresearch.org  的一篇文章《javap简介》,你可以在该网站的首页上通过查询该标题得到这
篇文章。
下面我们进入正题:

  • 第一例
     int i = 0;
     i=i++ + ++i;

     Code:
      0:   iconst_0          将 0 推到堆栈中//对应赋值语句 int i = 0;iconst_0中的0为初始值
      1:   istore_1          从堆栈中弹出这个值,并将它存储到局部变量表的索引 1 处 //对应赋值语句,上句是
                              赋值,这句是存储,索引1
    处即为i,因为没有其它变量,所以本例中局部变量的索引不变
      2:   iload_1           将局部变量表索引 1 处的值推到堆栈中//将局部变量索引1处的计算结果推入堆栈临时
                              存储,局部变量的索引从1
    开始,依此类推,这句意味着将变量i=0先推入堆栈临时存储
      3:   iinc    1, 1       局部变量表索引 1 处的变量加 1 //将变量i自加1,则此时变量i为1
      6:   iinc    1, 1       局部变量表索引 1 处的变量加 1 //再将变量i自加1,则此时变量i为2
      9:   iload_1           将局部变量表索引 1 处的值推到堆栈中//将变量i=2推入堆栈临时存储
      10:  iadd               从操作数堆栈中弹出两个整数并让它们相加。将得到的整数推回堆栈中//将两次暂存的
                             整数相加,即0+2=2
      11:  istore_1        从堆栈中弹出这个值,并将它存储到局部变量表的索引 1 处//把上步相加之结果弹出
                              堆栈
      12:  return             从堆栈中弹出值并将它推到调用方法的操作数栈中。退出方法//将i=2返回,计算结束
  • 第二例

    int i=0;
     i = ++i + i++;

     Code:
      0:   iconst_0          将 0 推到堆栈中//对应赋值语句 int i = 0;iconst_0中的0为初始值
      1:   istore_1           从堆栈中弹出这个值,并将它存储到局部变量表的索引 1 处 //对应赋值语句,上句
                            是赋值,这句是存储
      2:   iinc    1, 1       局部变量表索引 1 处的变量加 1 //将变量i自加1,则此时变量i为1
      5:   iload_1          将局部变量表索引 1 处的值推到堆栈中//将变量i=1推入堆栈临时存储
      6:   iload_1          将局部变量表索引 1 处的值推到堆栈中//将变量i=1推入堆栈临时存储
      7:   iinc    1, 1       局部变量表索引 1 处的变量加 1 //再将变量i自加1,则此时变量i为2
      10:  iadd               从操作数堆栈中弹出两个整数并让它们相加。将得到的整数推回堆栈中//将两次暂存的
                            整数相加,即0+2=2  注意:虽然上步让i=2,但是并没有推入堆栈作存储
      11:  istore_1         从堆栈中弹出这个值,并将它存储到局部变量表的索引 1 处//把上步相加之结果弹出堆栈
      12:  return             从堆栈中弹出值并将它推到调用方法的操作数栈中。退出方法//将i=2返回,计算结束
    ======================================================================================

      下面给出的是较为复杂一点的例子,供读者自行分析。

int i=0;
i= i++ + ++i;
int j=0;
j= ++j + ++j;

 Code:

 0:   iconst_0
 1:   istore_1
 2:   iload_1
 3:   iinc    1, 1
 6:   iinc    1, 1
 9:   iload_1
 10:  iadd
 11:  istore_1
 12:  iconst_0
 13:  istore_2
 14:  iinc    2, 1
 17:  iload_2
 18:  iinc    2, 1
 21:  iload_2
 22:  iadd
 23:  istore_2
 24:  return

 

0 0

相关博文

我的热门文章

img
取 消
img