【JVM】字节码指令 invokevirtual

文章讲述了Java虚拟机中的invokevirtual指令如何在运行时根据对象的实际类型执行虚方法调用,演示了多态性的动态分派过程。通过Dog子类重写Animal父类方法的例子,展示了即使使用Animal引用,也会调用Dog类的方法输出‘Dogbarks’。
摘要由CSDN通过智能技术生成

在Java虚拟机(JVM)中,invokevirtual 是一个字节码指令,用于调用对象实例的方法。它的主要作用是执行对象的虚方法调用,遵循Java语言中的动态分派机制。

例如,假设我们有以下Java代码:

Java

1public class Animal {
2    public void makeSound() {
3        System.out.println("Animal makes a sound");
4    }
5}
6
7public class Dog extends Animal {
8    @Override
9    public void makeSound() {
10        System.out.println("Dog barks");
11    }
12
13    public static void main(String[] args) {
14        Animal myPet = new Dog();
15        myPet.makeSound(); // 这行代码编译后将包含invokevirtual指令
16    }
17}

当JVM执行到 myPet.makeSound() 时,对应的字节码会包含 invokevirtual 指令,它的工作原理如下:

  • 首先,根据栈顶的对象引用找到实际的对象类型。在这个例子中,虽然变量 myPet 的静态类型是 Animal,但其实际类型是 Dog
  • JVM查找实际类型 Dog 中名为 makeSound 的方法签名,并执行该方法体。
  • 如果没有在实际类型中找到对应的方法,则按照继承关系向上查找父类直到找到合适的实现或者到达顶级父类(Object),如果没有找到则抛出 AbstractMethodError 或者 NoSuchMethodError 异常。

因此,在上述示例中,尽管通过 Animal 类型的引用调用了 makeSound 方法,但由于运行时的实际对象是 Dog 类型,所以最终执行的是 Dog 类中重写的 makeSound 方法,输出 “Dog barks”。这就是 invokevirtual 指令如何实现在运行时基于对象实际类型的多态性方法调用。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值