Hier, j'ai eu un entretien téléphonique technique de deux heures (que j'ai réussi, woohoo!), Mais j'ai complètement étouffé la question suivante concernant la liaison dynamique en Java. Et c'est doublement déroutant parce que j'avais l'habitude d'enseigner ce concept aux étudiants de premier cycle quand j'étais TA il y a quelques années, donc la perspective que je leur ai donné de la désinformation est un peu dérangeante ...
Voici le problème qui m'a été posé:
/* What is the output of the following program? */
public class Test {
public boolean equals( Test other ) {
System.out.println( "Inside of Test.equals" );
return false;
}
public static void main( String [] args ) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println( count++ );// prints 0
t1.equals( t2 ) ;
System.out.println( count++ );// prints 1
t1.equals( t3 );
System.out.println( count++ );// prints 2
t3.equals( o1 );
System.out.println( count++ );// prints 3
t3.equals(t3);
System.out.println( count++ );// prints 4
t3.equals(t2);
}
}
J'ai affirmé que la sortie aurait dû être deux instructions d'impression distinctes issues de la equals()
méthode remplacée : at t1.equals(t3)
et t3.equals(t3)
. Le dernier cas est assez évident, et avec le premier cas, même s'il t1
a une référence de type Object, il est instancié en tant que type Test, donc la liaison dynamique doit appeler la forme surchargée de la méthode.
Apparemment non. Mon enquêteur m'a encouragé à exécuter le programme moi-même, et voilà, il n'y avait qu'une seule sortie de la méthode remplacée: à la ligne t3.equals(t3)
.
Ma question est alors: pourquoi? Comme je l'ai déjà mentionné, même s'il t1
s'agit d'une référence de type Object (de sorte que la liaison statique appellerait la equals()
méthode Object ), la liaison dynamique devrait prendre soin d'invoquer la version la plus spécifique de la méthode en fonction du type instancié de la référence. Qu'est-ce que je rate?