Ayer tuve una entrevista telefónica técnica de dos horas (que pasé, ¡woohoo!), Pero borré por completo la siguiente pregunta sobre el enlace dinámico en Java. Y es doblemente desconcertante porque solía enseñar este concepto a estudiantes universitarios cuando era asistente técnico hace unos años, por lo que la perspectiva de que les di información errónea es un poco inquietante ...
Aquí está el problema que me dieron:
/* 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);
}
}
Afirmé que la salida debería haber sido dos declaraciones de impresión separadas desde el equals()
método anulado : at t1.equals(t3)
y t3.equals(t3)
. El último caso es bastante obvio, y con el primer caso, aunque t1
tiene una referencia de tipo Object, se instancia como tipo Test, por lo que el enlace dinámico debería llamar a la forma anulada del método.
Aparentemente no. Mi entrevistador me animó a ejecutar el programa yo mismo, y he aquí, solo había una salida del método anulado: en la línea t3.equals(t3)
.
Entonces mi pregunta es, ¿por qué? Como ya mencioné, aunque t1
es una referencia de tipo Object (por lo que el enlace estático invocaría el equals()
método de Object ), el enlace dinámico debería encargarse de invocar la versión más específica del método según el tipo instanciado de la referencia. ¿Qué me estoy perdiendo?