次のコードがあります。
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() を呼び出す必要があります。
ただし、invokevirtual は、ターゲット メソッドが Object によって継承されている場合に限り、一貫性を維持しません。
その場合のみ、invokevirtual はオブジェクト内のメソッドを呼び出します。それ以外の場合は、invokevirtual が現在のクラスのメソッドを呼び出します。
なぜこれが起こるのか知りたいです。