【参考】JVM根据字节码指令介绍方法执行流程

 在上一篇博客中介绍了《Class文件结构》,其中就提到了一个例子,下面我们依然根据该例子的字节码来对方法的执行流程进行讲解。

    public class TestClass{  

  1.     private int num;  
  2.       
  3.     public int inc(){  
  4.         for(int i=0; i<10; i++){  
  5.             num = i;  
  6.         }  
  7.         return num;  
  8.     }  
  9.       
  10.     public static void main(String[] args){  
  11.         new TestClass().inc();  
  12.     }  
  13.       
  14. }  

使用javap -verbose命令反编译后,输出常量表和字节码如下:

  1. D:\JVM>javap -verbose TestClass  
  2. Compiled from "TestClass.java"  
  3. public class TestClass extends java.lang.Object  
  4.   SourceFile: "TestClass.java"  
  5.   minor version: 0  
  6.   major version: 50  
  7.   Constant pool:  
  8. const #1 = Method       #6.#20; //  java/lang/Object."<init>":()V  
  9. const #2 = Field        #3.#21; //  TestClass.num:I  
  10. const #3 = class        #22;    //  TestClass  
  11. const #4 = Method       #3.#20; //  TestClass."<init>":()V  
  12. const #5 = Method       #3.#23; //  TestClass.inc:()I  
  13. const #6 = class        #24;    //  java/lang/Object  
  14. const #7 = Asciz        num;  
  15. const #8 = Asciz        I;  
  16. const #9 = Asciz        <init>;  
  17. const #10 = Asciz       ()V;  
  18. const #11 = Asciz       Code;  
  19. const #12 = Asciz       LineNumberTable;  
  20. const #13 = Asciz       inc;  
  21. const #14 = Asciz       ()I;  
  22. const #15 = Asciz       StackMapTable;  
  23. const #16 = Asciz       main;  
  24. const #17 = Asciz       ([Ljava/lang/String;)V;  
  25. const #18 = Asciz       SourceFile;  
  26. const #19 = Asciz       TestClass.java;  
  27. const #20 = NameAndType #9:#10;//  "<init>":()V  
  28. const #21 = NameAndType #7:#8;//  num:I  
  29. const #22 = Asciz       TestClass;  
  30. const #23 = NameAndType #13:#14;//  inc:()I  
  31. const #24 = Asciz       java/lang/Object;  
  32.   
  33. {  
  34. public TestClass();  
  35.   Code:  
  36.    Stack=1, Locals=1, Args_size=1  
  37.    0:   aload_0  
  38.    1:   invokespecial   #1; //Method java/lang/Object."<init>":()V  
  39.    4:   return  
  40.   LineNumberTable:  
  41.    line 10  
  42.   
  43.   
  44. public int inc();  
  45.   Code:  
  46.    Stack=2, Locals=2, Args_size=1  
  47.    0:   iconst_0        //定义一个常量0,放入操作数栈  
  48.    1:   istore_1        //把该常量弹出栈顶存入到局部变量表  
  49.    2:   iload_1         //把该局部变量放入操作数栈  
  50.    3:   bipush  10      //把常量10放入操作数栈  
  51.    5:   if_icmpge   19  //把i和10进行比较  
  52.    8:   aload_0         //加载局部变量表index为0的变量放入操作数栈  
  53.    9:   iload_1         //加载局部变量表index为1的变量放入操作数栈  
  54.    10:  putfield        #2; //Field num:I   //把i的值赋给num字段  
  55.    13:  iinc    11    //局部变量i自增1  
  56.    16:  goto    2       //跳转到第2行  
  57.    19:  aload_0         //加载局部变量表index为0的变量放入操作数栈  
  58.    20:  getfield        #2; //Field num:I   //获取字段num的值  
  59.    23:  ireturn         //返回  
  60.   LineNumberTable:  
  61.    line 50  
  62.    line 68  
  63.    line 513  
  64.    line 819  
  65.   
  66.   StackMapTable: number_of_entries = 2  
  67.    frame_type = 252 /* append */  
  68.      offset_delta = 2  
  69.      locals = [ int ]  
  70.    frame_type = 250 /* chop */  
  71.      offset_delta = 16  
  72.   
  73.   
  74. public static void main(java.lang.String[]);  
  75.   Code:  
  76.    Stack=2, Locals=1, Args_size=1  
  77.    0:   new     #3; //class TestClass  
  78.    3:   dup  
  79.    4:   invokespecial   #4; //Method "<init>":()V //调用实例初始化方法  
  80.    7:   invokevirtual   #5; //Method inc:()I        //调用普通方法inc()  
  81.    10:  pop  
  82.    11:  return  
  83.   LineNumberTable:  
  84.    line 120  
  85.    line 1311  
  86.   
  87.   
  88. }  

方法的调用指令分为以下几种:

  1. invokevirtual指令用于调用所有的虚方法。
  2. invokeinterface指令用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
  3. invokespecial指令用于调用一些需要特殊处理的实例方法,包括实例构造器<init>化方法、私有方法和父类方法。
  4. invokestatic指令用于调用静态方法(static方法)。

其它具体的指令可以参考:字节码指令集

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值