Hier, j'ai passé un entretien téléphonique technique de deux heures (que j'ai réussi, ouf !), mais j'ai complètement raté la question suivante concernant les liaisons dynamiques en Java. C'est d'autant plus curieux que j'avais l'habitude d'enseigner ce concept à des étudiants de premier cycle lorsque j'étais assistant technique il y a quelques années, alors la perspective que je leur ai donné des informations erronées est un peu troublante...
Voici le problème qui m'a été soumis :
/* 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 constituée de deux instructions d'impression distinctes à l'intérieur de la directive surchargée. equals()
méthode : à t1.equals(t3)
et t3.equals(t3)
. Le dernier cas est assez évident, et avec le premier cas, même si t1
a une référence de type Object, il est instancié comme type Test, donc la liaison dynamique doit appeler la forme surchargée de la méthode.
Apparemment pas. Mon interlocuteur m'a encouragé à exécuter le programme moi-même, et voilà qu'il n'y avait qu'une seule sortie de la méthode surchargée : à la ligne t3.equals(t3)
.
Ma question est donc la suivante : pourquoi ? Comme je l'ai déjà mentionné, même si t1
est une référence de type Object (la liaison statique invoquerait donc la fonction equals()
), la liaison dynamique devrait se chargent d'invoquer la version la plus spécifique de la méthode en fonction du type instancié de la référence. Que me manque-t-il ?