gpt4 book ai didi

Java字节码操作 'invokevirtual' Object继承的方法不保持一致性

转载 作者:搜寻专家 更新时间:2023-10-31 19:29:03 25 4
gpt4 key购买 nike

我有以下代码。

public class Parent {

@Override
public int hashCode() {
return 0;
}

}

public class Child extends Parent {

public void test() {
this.toString();
this.hashCode();
}

}

正如您在上面的代码中看到的,Child 继承了 Object 的 toString() 和 Parent 的 hashCode()。Child#test的字节码操作如下。

ALOAD 0: this
INVOKEVIRTUAL Object.toString() : String
ALOAD 0: this
INVOKEVIRTUAL Child.hashCode() : int
RETURN

我认为如果 invokevirtual 调用 Object.toString(),它应该调用 Parent.hashCode() 以保持一致性。或者,调用 Child.hashCode(),然后调用 Child.toString()。

然而,当且仅当目标方法被 Object 继承时,invokevirtual 不保持一致性。

只有那种情况,invokevirtual 调用对象中的方法。对于其他情况, invokevirtual 调用当前类中的方法。

我想知道为什么会这样。

最佳答案

根据 JVM specification p. 3.7 :

The compiler does not know the internal layout of a class instance. Instead, it generates symbolic references to the methods of an instance, which are stored in the runtime constant pool. Those runtime constant pool items are resolved at runtime to determine the actual method location.

这意味着所有这些符号 Child.hashCode() 都只是常量,它们并没有指定某种 JVM 如何调用此方法。看起来,对于 toString() 方法,编译器知道,该方法在 Object 类中有其基础实现,因此它将符号常量放入 Object 常量池中的类 - 这是某种优化,它使编译器适用于 JVM:

  Constant pool:
const #2 = Method #24.#25; // java/lang/Object.toString:()Ljava/lang/String;
...
const #24 = class #34; // java/lang/Object
const #25 = NameAndType #35:#36;// toString:()Ljava/lang/String;

关于Java字节码操作 'invokevirtual' Object继承的方法不保持一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15172269/

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