gpt4 book ai didi

javac 生成一个桥接方法,其中包含指向抽象方法的 invokespecial 指令

转载 作者:行者123 更新时间:2023-12-02 05:38:32 26 4
gpt4 key购买 nike

假设以下实际代码结构:

interface I {
I m();
}

abstract class A implements I {
@Override
public abstract A m();

abstract class B extends A {

}
}

为B生成的字节码是

abstract class A$B extends A {
<some stuff>

public I m(); //bridge method
Code:
0: aload_0
1: invokespecial #2 // Method A.m:()LA;
4: areturn
}

注意指向抽象方法A.m()的invokespecial指令的使用。在我看来,根据 invokespecial 上的 JVM 8 规范,这一定会在运行时导致 AbstractMethodError 。 :

If all of the following are true, let C be the direct superclass of the current class.

因此,在我们的示例中,A 将被选为 C。

The actual method to be invoked is selected by the following lookup procedure.

1) If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.

所以JVM会选择A.m()。

但是运行时异常部分指出:

Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects an abstract method, invokespecial throws an AbstractMethodError.

因此调用该方法将以错误结束。

我只是想知道,为什么Java编译器会生成这样的被判失败的字节码?

附注我猜测上述桥接方法根本不会被调用,因为 A.B 类的最终实现者将覆盖它。但随之而来的问题就出现了:java生成这个桥接方法的目的是为了什么?

最佳答案

我不太明白你想达到什么目的。您想了解为什么会生成该方法吗?

Notice the use of invokespecial instruction pointing to the abstract method A.m(). In my opinion this must lead to an AbstractMethodError at runtime

理论上不应该存在抽象类的实例,任何实例化的子类都必须实现所有抽象方法。所以invokespecial指向实现子类。尝试实例化抽象类通常会被编译器捕获。

当没有找到实现子类时会抛出AbstractMethodError,大多数情况下,当按预期加载不同的类版本或使用字节码操作时,会发生这种情况。

关于javac 生成一个桥接方法,其中包含指向抽象方法的 invokespecial 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42566298/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com