Вчера у меня было двухчасовое собеседование по телефону по техническим вопросам (которое я прошел, у-у-у!), Но я полностью не ответил на следующий вопрос, касающийся динамического связывания в Java. И это вдвойне озадачивает, потому что я учил этой концепции студентов, когда был ТА несколько лет назад, поэтому перспектива того, что я дал им дезинформацию, немного тревожит ...
Вот проблема, которую мне дали:
/* 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);
}
}
Я утверждал, что на выходе должны были быть два отдельных оператора печати из переопределенного equals()
метода: at t1.equals(t3)
и t3.equals(t3)
. Последний случай достаточно очевиден, и в первом случае, даже если t1
имеется ссылка на тип Object, он создается как тип Test, поэтому динамическое связывание должно вызывать переопределенную форму метода.
Очевидно нет. Мой интервьюер посоветовал мне запустить программу самостоятельно, и, о чудо, был только один результат переопределенного метода: в строке t3.equals(t3)
.
Тогда мой вопрос: почему? Как я уже упоминал, даже если t1
это ссылка типа Object (поэтому статическая привязка будет вызывать equals()
метод Object ), динамическая привязка должна позаботиться о вызове наиболее конкретной версии метода на основе созданного типа ссылки. Что мне не хватает?