Ho i seguenti codici.L'operazione bytecode Java 'invokevirtual' non mantiene la coerenza per i metodi ereditati dall'oggetto
public class Parent {
@Override
public int hashCode() {
return 0;
}
}
public class Child extends Parent {
public void test() {
this.toString();
this.hashCode();
}
}
Come si vede nei codici di cui sopra, figlio eredita toString() da Object e hashCode() da Parent. L'operazione Bytecode del test N. figlio è la seguente.
ALOAD 0: this
INVOKEVIRTUAL Object.toString() : String
ALOAD 0: this
INVOKEVIRTUAL Child.hashCode() : int
RETURN
penso che se invokevirtual chiama Object.toString(), si dovrebbe chiamare Parent.hashCode() per la coerenza. oppure, chiamato Child.hashCode(), quindi deve essere chiamato Child.toString().
Tuttavia, invokevirtual non mantiene la coerenza se e solo se il metodo di destinazione è ereditato da Object.
Solo quel caso, metodo chiamate invokevirtual nell'oggetto. Per altri casi, il metodo invokevirtual chiama nella classe corrente.
Voglio sapere perché questo accade.
Dato che il metodo effettivo eseguito * sarà * sempre basato sul tipo effettivo al momento dell'esecuzione, perché questo è importante? Sono equivalenti, sicuramente? –
Forse il compilatore è un'ereditarietà di casing speciale da Object, perché è un caso molto comune. –
E come impatta la tua logica? – CuriousMind