zoukankan      html  css  js  c++  java
  • 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方法表中的方法,如果没有,向上查找父类的方法表,找到后,调用父类方法表中的方法。

     

  • 相关阅读:
    C++并发与多线程学习笔记--unique_lock详解
    C++并发与多线程学习笔记--互斥量、用法、死锁概念
    MongoDB教程--配置与入门
    C++并发与多线程学习笔记--多线程数据共享问题
    C++并发与多线程学习笔记--参数传递详解
    C++并发与多线程学习笔记--基本概念和实现
    Python学习笔记--语音处理初步
    C#中三个关键字params,Ref,out
    Windows窗体应用开发3--配置标准控件1
    在博客的第一天
  • 原文地址:https://www.cnblogs.com/jthr/p/15742781.html
Copyright © 2011-2022 走看看