昨天我进行了两个小时的技术电话面试(我通过了,呜呼!),但是我完全搞砸了下面关于 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()
方法中的两个单独的 print 语句: 在 t1.equals(t3)
和 t3.equals(t3)
。后一种情况显而易见,对于前一种情况,即使 t1
具有 Object 类型的引用,它也被实例化为 Test 类型,因此动态绑定应该调用方法的重写形式。
显然不是。我的面试官鼓励我自己运行这个程序,你瞧,这个被覆盖的方法只有一个输出: 在 t3.equals(t3)
行。
我的问题是,为什么?正如我已经提到的,即使 t1
是 Object 类型的引用(因此静态绑定将调用 Object 的 equals()
方法) ,动态绑定 应该负责根据引用的实例化类型调用方法的最特定版本。我错过了什么?