深入理解Java虚拟机——方法调用(动态分派调用)

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Java虚拟机——方法调用(动态分派调用)相关的知识,希望对你有一定的参考价值。

目录

一、动态分派调用

1.1、方法动态分派调用演示

  • 示例代码

    /**
     * @description: 动态分配调用示例
     * @author: xz
     */
    public class Test4 
    
        static class Parent
            public void hello()
                System.out.println("hello parent");
            
        
    
        static class Child1 extends Parent
            @Override
            public void hello() 
                System.out.println("hello Child1");
            
        
    
        static class Child2 extends Parent
            @Override
            public void hello() 
                System.out.println("hello Child2");
            
        
    
        public static void main(String[] args) 
            Parent p1 = new Child1();
            Parent p2 = new Child2();
            p1.hello();
            p2.hello();
        
    
    
  • 输出结果

  • 总结
    显然这里不可能再根据静态类型来决定,因为静态类型同样都是Parent的两个变量p1和p2在调用hello()方法时执行了不同的行为,并且变量p1在两次调用中执行了不同的方法。

1.2、方法动态分派调用的原因

  • 使用javap命令输出这段代码的字节码,尝试从中寻找答案。

  • 原因就需要从invokevirtual指令的多态查找过程开始说起,invokevirtual指令的运行时解析过程大致分为以下几个步骤:
    (1)、找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C。
    (2)、如果在类型C中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;如果不通过,则返回java.lang.IllegalAccessError异常。
    (3)、否则,按照继承关系从下往上一次对C的各个父类进行第(2)步的搜索和验证过程。
    (4)、如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。

以上是关于深入理解Java虚拟机——方法调用(动态分派调用)的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Java虚拟机——方法调用(静态分派调用)

深入理解Java虚拟机——方法调用(静态分派调用)

深入理解Java虚拟机——方法调用和返回指令

深入理解Java虚拟机——方法调用和返回指令

深入理解Java虚拟机——方法调用(解析调用)

深入Java虚拟机之五:多态性实现机制——静态分派与动态分派