• JAVA虚拟机16方法的动态调用


    更详细:https://www.cnblogs.com/jthr/p/15762527.html

    1.子类重写父类方法

    1.1父类

    public class Father {
    
        public int num = 20;
    
        public int get()
        {
    
            System.out.println("father-get");
    
            return num;
        }
    
    
        public void fatherMethod(){
    
        }
    }

    1.2子类

    public class Son extends Father{
    
        public int num = 10;
    
        public int get(){
            System.out.println("son-get");
            return num;
        }
    
    
    
        public static void main(String[] args) {
            Father s = new Son();
            System.out.println(s.num);
            System.out.println(s.get());
    
        }
    }

    1.3执行结果

    20
    son-get
    10

    可以看到s.num输出的是父类的值

    get方法调用的是子类的方法,输出的是子类的值

    1.4使用 javap -verbose查看Son.class文件

    看main方法

     可以看到,

    s.num
    s.get

    都是父类的字段和方法

    那么在执行时,却是父类的字段,子类的方法呢?

    2.方法调用

    2.1分类

     Java 的方法调用有两类,动态方法调用与静态方法调用。静态方法调用是指对于类的静态方法的调用方式,是静态绑定的;而动态方法调用需要有方法调用所作用的对象,是动态绑定的。类调用 (invokestatic) 是在编译时刻就已经确定好具体调用方法的情况,而实例调用 (invokevirtual) 则是在调用的时候才确定具体的调用方法,这就是动态绑定,也是多态要解决的核心问题。

    JVM 的方法调用指令有四个,分别是 invokestatic,invokespecial,invokesvirtual 和 invokeinterface。前两个是静态绑定,后两个是动态绑定的。本文也可以说是对于 JVM 后两种调用实现的考察。

    2.2动态调用

    上面的例子,编译时,s的类型是Father

    invokevirtual 指令指向的是#10,也就是father的get方法

      而真正调用方法时,根据实例this得到对象实际上是Son,它会先去查找Son方法表中的方法,如果有,调用Son方法表中的方法,如果没有,向上查找父类的方法表,找到后,调用父类方法表中的方法。

     

  • 相关阅读:
    RBAC概念
    Django框架的优缺点
    全文检索whoosh
    软件项目管理|期末复习(九)
    软件项目管理|期末复习(十四)
    HOJX 1003| Mixing Milk
    [转发]ACM刷题网站
    [转发]软件工具|Github上整理的一些工具
    软件项目管理|期末复习(三)
    计算机图形学|两道习题
  • 原文地址:https://www.cnblogs.com/jthr/p/15742781.html
Copyright © 2020-2023  润新知