MST

星途 面试题库

面试题:Java多态下父类与子类方法调用优先级之动态绑定与字节码分析

考虑以下Java代码: class Base { public void method() { System.out.println("Base method"); } } class Derived1 extends Base { @Override public void method() { System.out.println("Derived1 method"); } } class Derived2 extends Base { @Override public void method() { System.out.println("Derived2 method"); } } public class Main { public static void main(String[] args) { Base obj = Math.random() > 0.5? new Derived1() : new Derived2(); obj.method(); } } 从字节码层面分析,Java虚拟机是如何实现这种多态下父类与子类方法调用优先级机制的,也就是动态绑定的过程?请详细描述涉及的字节码指令以及它们的作用。
43.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 字节码指令概述
    • 在Java字节码层面,动态绑定主要通过 invokevirtual 指令实现。
  2. 具体字节码指令及作用
    • invokevirtual 指令
      • 指令格式invokevirtual indexbyte1 indexbyte2
      • 作用invokevirtual 指令用于调用对象的实例方法,根据对象的实际类型(运行时类型)来决定调用哪个方法。它会在运行时从对象的实际类型的虚方法表(vtable)中查找并调用相应的方法。
      • 在上述代码中,obj.method(); 这行代码编译后会生成 invokevirtual 指令。当执行到这一指令时,Java 虚拟机首先获取 obj 的实际运行时类型(Derived1Derived2)。然后,根据这个实际类型在其对应的虚方法表中查找 method 方法的具体实现地址。最后,调用找到的方法实现,从而实现了动态绑定。
    • 其他相关指令
      • new 指令:在 Base obj = Math.random() > 0.5? new Derived1() : new Derived2(); 这行代码中,new 指令用于在堆上创建 Derived1Derived2 对象的实例。
      • dup 指令:通常在 new 指令之后使用,用于复制栈顶元素。因为 new 指令会在栈顶压入新创建对象的引用,dup 指令复制这个引用,以便后续可以对该对象进行初始化等操作。
      • invokespecial 指令:用于调用实例构造方法(<init> 方法)、私有方法及父类方法。在创建 Derived1Derived2 对象时,会使用 invokespecial 指令调用其父类 Base 的构造方法。

在整个动态绑定过程中,invokevirtual 指令起到了核心作用,结合其他指令,Java 虚拟机能够在运行时根据对象的实际类型准确地调用相应的方法,实现多态特性。