美文网首页工作生活
jvm调用方法的过程

jvm调用方法的过程

作者: 杨殿生 | 来源:发表于2019-07-03 15:44 被阅读0次
    public class Test {
        public void foo(){
            bar();
        }
        public void bar(){
        }
    }
    
    Classfile /Users/yangdiansheng/Desktop/javacode/JavaTest/out/production/JavaTest/Test.class
      Last modified 2019-7-2; size 381 bytes
      MD5 checksum 8df2469155792718b33ba9c334da87c3
      Compiled from "Test.java"
    public class Test
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #4.#16         // java/lang/Object."<init>":()V
       #2 = Methodref          #3.#17         // Test.bar:()V
       #3 = Class              #18            // Test
       #4 = Class              #19            // java/lang/Object
       #5 = Utf8               <init>
       #6 = Utf8               ()V
       #7 = Utf8               Code
       #8 = Utf8               LineNumberTable
       #9 = Utf8               LocalVariableTable
      #10 = Utf8               this
      #11 = Utf8               LTest;
      #12 = Utf8               foo
      #13 = Utf8               bar
      #14 = Utf8               SourceFile
      #15 = Utf8               Test.java
      #16 = NameAndType        #5:#6          // "<init>":()V
      #17 = NameAndType        #13:#6         // bar:()V
      #18 = Utf8               Test
      #19 = Utf8               java/lang/Object
    {
      public Test();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 1: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   LTest;
    
      public void foo();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokevirtual #2                  // Method bar:()V
             4: return
          LineNumberTable:
            line 4: 0
            line 5: 4
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   LTest;
    
      public void bar();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=0, locals=1, args_size=1
             0: return
          LineNumberTable:
            line 9: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       1     0  this   LTest;
    }
    SourceFile: "Test.java"
    
    

    方法表
    https://blog.csdn.net/luanlouis/article/details/41113695

    直接引用和符号引用
    https://blog.csdn.net/u014656992/article/details/51107127


    public class Test implements Father{
    
        private int aa = 0;
        protected float bb = 1;
        public Test test = new Test();
    
        public static void main(String[] args){
            Test test = new Test();
            try {
                int sum = test.sum(1,2);
                if (sum == 3){
                    test.foo();
                }
            } catch (Exception e){
    
            }
        }
    
        public void foo(){
            System.out.println("sum = " + 3);
        }
    
        public int sum(int i,int j){
            return i + j;
        }
    
        @Override
        public void show() {
            foo();
        }
    }
    
    
    Classfile /Users/yangdiansheng/Desktop/javacode/JavaTest/out/production/JavaTest/Test.class
      Last modified 2019-7-3; size 1045 bytes
      MD5 checksum 043f5cd328f8fa88b0e8f594b399495e
      Compiled from "Test.java"
    public class Test implements Father
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #13.#42        // java/lang/Object."<init>":()V
       #2 = Fieldref           #4.#43         // Test.aa:I
       #3 = Fieldref           #4.#44         // Test.bb:F
       #4 = Class              #45            // Test
       #5 = Methodref          #4.#42         // Test."<init>":()V
       #6 = Fieldref           #4.#46         // Test.test:LTest;
       #7 = Methodref          #4.#47         // Test.sum:(II)I
       #8 = Methodref          #4.#48         // Test.foo:()V
       #9 = Class              #49            // java/lang/Exception
      #10 = Fieldref           #50.#51        // java/lang/System.out:Ljava/io/PrintStream;
      #11 = String             #52            // sum = 3
      #12 = Methodref          #53.#54        // java/io/PrintStream.println:(Ljava/lang/String;)V
      #13 = Class              #55            // java/lang/Object
      #14 = Class              #56            // Father
      #15 = Utf8               aa
      #16 = Utf8               I
      #17 = Utf8               bb
      #18 = Utf8               F
      #19 = Utf8               test
      #20 = Utf8               LTest;
      #21 = Utf8               <init>
      #22 = Utf8               ()V
      #23 = Utf8               Code
      #24 = Utf8               LineNumberTable
      #25 = Utf8               LocalVariableTable
      #26 = Utf8               this
      #27 = Utf8               main
      #28 = Utf8               ([Ljava/lang/String;)V
      #29 = Utf8               sum
      #30 = Utf8               args
      #31 = Utf8               [Ljava/lang/String;
      #32 = Utf8               StackMapTable
      #33 = Class              #45            // Test
      #34 = Class              #49            // java/lang/Exception
      #35 = Utf8               foo
      #36 = Utf8               (II)I
      #37 = Utf8               i
      #38 = Utf8               j
      #39 = Utf8               show
      #40 = Utf8               SourceFile
      #41 = Utf8               Test.java
      #42 = NameAndType        #21:#22        // "<init>":()V
      #43 = NameAndType        #15:#16        // aa:I
      #44 = NameAndType        #17:#18        // bb:F
      #45 = Utf8               Test
      #46 = NameAndType        #19:#20        // test:LTest;
      #47 = NameAndType        #29:#36        // sum:(II)I
      #48 = NameAndType        #35:#22        // foo:()V
      #49 = Utf8               java/lang/Exception
      #50 = Class              #57            // java/lang/System
      #51 = NameAndType        #58:#59        // out:Ljava/io/PrintStream;
      #52 = Utf8               sum = 3
      #53 = Class              #60            // java/io/PrintStream
      #54 = NameAndType        #61:#62        // println:(Ljava/lang/String;)V
      #55 = Utf8               java/lang/Object
      #56 = Utf8               Father
      #57 = Utf8               java/lang/System
      #58 = Utf8               out
      #59 = Utf8               Ljava/io/PrintStream;
      #60 = Utf8               java/io/PrintStream
      #61 = Utf8               println
      #62 = Utf8               (Ljava/lang/String;)V
    {
      private int aa;
        descriptor: I
        flags: ACC_PRIVATE
    
      protected float bb;
        descriptor: F
        flags: ACC_PROTECTED
    
      public Test test;
        descriptor: LTest;
        flags: ACC_PUBLIC
      //无参构造函数
      public Test();
        //方法描述符
        descriptor: ()V
        //访问权限
        flags: ACC_PUBLIC
        //执行指令存储在code中
        Code:
          //stack操作数栈最大深度,locals局部变量表中变量数,args_size参数
          stack=3, locals=1, args_size=1
             //将局部变量表第0位置入操作数栈 ,super父类构造函数
             0: aload_0 . 
             //调用父类构造方法
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             //this引用入栈
             4: aload_0
             //int类型常量入栈
             5: iconst_0
             //成员变量赋值 
             6: putfield      #2                  // Field aa:I
             //this引用入栈
             9: aload_0
             //float类型常量入栈
            10: fconst_1
             //成员变量赋值 
            11: putfield      #3                  // Field bb:F
             //this引用入栈
            14: aload_0
             //创建实例
            15: new           #4                  // class Test
             //复制栈顶
            18: dup
             //执行<init>方法,也就是对象初始化方法
            19: invokespecial #5                  // Method "<init>":()V
             //成员变量赋值
            22: putfield      #6                  // Field test:LTest;
            //返回
            25: return
          LineNumberTable:
            line 3: 0
            line 5: 4
            line 6: 9
            line 7: 14
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      26     0  this   LTest;
    
      public static void main(java.lang.String[]);
        descriptor: ([Ljava/lang/String;)V
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=3, locals=3, args_size=1
             //创建实例
             0: new           #4                  // class Test
             //复制栈顶
             3: dup
             //调用<init方法>
             4: invokespecial #5                  // Method "<init>":()V
             //存储数值到局部变量表位置1,此时test局部变量赋值完毕
             7: astore_1
             //局部变量表1位置转载到栈
             8: aload_1
              //int类型常量入栈  
             9: iconst_1
             //int类型常量入栈
            10: iconst_2
             //调用sum方法
            11: invokevirtual #7                  // Method sum:(II)I
             //存储数值到局部变量表位置2,此时sum赋值完毕
            14: istore_2
             //int类型常量入栈,sum中值入栈
            15: iload_2
             // int类型常量入栈        
            16: iconst_3
             // 比较指令
            17: if_icmpne     24
             //取对象test
            20: aload_1
             // 调用foo()方法
            21: invokevirtual #8                  // Method foo:()V
             // 跳转指令
            24: goto          28
             // 
            27: astore_2
            28: return
          Exception table:
             from    to  target type
                 8    24    27   Class java/lang/Exception
          LineNumberTable:
            line 10: 0
            line 12: 8
            line 13: 15
            line 14: 20
            line 18: 24
            line 16: 27
            line 19: 28
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
               15       9     2   sum   I
                0      29     0  args   [Ljava/lang/String;
                8      21     1  test   LTest;
          StackMapTable: number_of_entries = 3
            frame_type = 252 /* append */
              offset_delta = 24
              locals = [ class Test ]
            frame_type = 66 /* same_locals_1_stack_item */
              stack = [ class java/lang/Exception ]
            frame_type = 0 /* same */
    
      public void foo();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             //访问static字段
             0: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
             //常量压入栈
             3: ldc           #11                 // String sum = 3
             //调用println方法
             5: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
             8: return
          LineNumberTable:
            line 22: 0
            line 23: 8
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       9     0  this   LTest;
    
      public int sum(int, int);
        descriptor: (II)I
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=3, args_size=3
             0: iload_1
             1: iload_2
             2: iadd
             3: ireturn
          LineNumberTable:
            line 26: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       4     0  this   LTest;
                0       4     1     i   I
                0       4     2     j   I
    
      public void show();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokevirtual #8                  // Method foo:()V
             4: return
          LineNumberTable:
            line 31: 0
            line 32: 4
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   LTest;
    }
    
    

    相关文章

      网友评论

        本文标题:jvm调用方法的过程

        本文链接:https://www.haomeiwen.com/subject/scizcctx.html