昨天我接受了两个小时的技术电话面试(我通过了,woohoo!),但是我完全想出了以下有关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类型的引用(因此静态绑定将调用Object的equals()
方法),动态绑定也应根据引用的实例化类型来调用方法的最特定版本。我想念什么?