美文网首页工作生活
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://blog.csdn.net/luanlouis/article/details/411136...

  • 一个关于实例对象初始化的题

    由以上代码分析类加载过程:jvm首先加载App类进内存(由于存在main方法,jvm调用某个类的静态方法,那么这个...

  • JVM系列之 _call_stub_entry初始化

    在上文JVM系列之函数调用入门已经简单介绍了JVM是如何调用方法的:JVM先调用call_stub()方法将_ca...

  • java动态绑定和多态实现原理

    在java方法调用过程中,jvm是如何知道具体调用哪个类的方法? 我们常常听到的静态和动态方法调用有什么区别呢...

  • JVM方法调用

    JVM方法调用 背景 Java文件在编译过程中不会进行传统编译的连接步骤,方法调用的目标方法以符号引用的方式存储在...

  • JVM--方法调用

    方法调用不是方法执行,方法调用是让jvm确定调用哪个方法,所以,程序运行时的它是最普遍、最频繁的操作。jvm需要在...

  • 4.JVM体系-对象的创建

    一、JVM体系-对象的创建 问题:JVM在方法的调用过程中,是怎样创建对象的? 1.对象在堆中如何创建: 3.1 ...

  • JVM方法调用

    方法重载和方法重写多态是面向对象程序设计的重要特性,方法重载和方法重写是Java语言实现多态的主要形式。方法重载指...

  • JVM 方法调用

    虚方法和非虚方法 先来看广义上的定义(即指Java代码层面): 非虚方法:如果方法在编译期就确定了具体的调用版本,...

  • JVM的方法调用

    方法调用并等同于方法中的代码被执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还未涉...

网友评论

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

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