我有以下代码。
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调用方法。
我想知道为什么会这样。
最佳答案
您是正确的,编译器的行为不合逻辑。但是此代码的效果与您建议的两种变体的效果相同。因此,这可能不是故意的行为,而是编译器代码长期演进的结果。其他编译器可能会生成不同的代码。