昨日、2時間の技術的な電話インタビュー(私は合格しました、woohoo!)を行いましたが、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()
メソッド内からの2つの別個の印刷ステートメントであるはずだと断言しました:at t1.equals(t3)
とt3.equals(t3)
。後者のケースは十分明白であり、前者のケースでt1
は、Object型の参照があっても、それはTest型としてインスタンス化されるため、動的バインディングはオーバーライドされた形式のメソッドを呼び出す必要があります。
どうやらそうではない。私のインタビュアーは私にプログラムを自分で実行するように勧めました、そして見れば、オーバーライドされたメソッドからの単一の出力しかありませんでした:行でt3.equals(t3)
。
私の質問は、なぜですか?すでに述べたように、t1
Object型の参照であっても(静的バインディングはObjectのequals()
メソッドを呼び出す)、動的バインディングはインスタンス化された参照の型に基づいて、メソッドの最も具体的なバージョンの呼び出しを処理する必要があります。何が欠けていますか?