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