3

以下のコードで、 evenをo1.equals(o2);呼び出しequals(Object o)ていないのに、タイプのオブジェクトを参照しているのはなぜですか!equals(EqualsTest et)o1o2EqualsTest

public class EqualsTest {
      public static <T> boolean equalTest(T o1, T o2) {
          return o1.equals(o2);
      }
      public static void main(String[] args) {
          EqualsTest et1 = new EqualsTest();
          EqualsTest et2 = new EqualsTest();
          System.out.println(et1.equals(et2));
          System.out.println(equalTest(et1, et2));
      }
      public boolean equals(Object o) {
          if (o instanceof EqualsTest) {
              System.out.println("equals(Object)");
              return true;
          }
          return false;
      }
      public boolean equals(EqualsTest et) {
          System.out.println("equals(EqualsTest)");
          return this.equals((Object)et);
      }
}
4

3 に答える 3

1

コメントで述べたように、それはTypeErasureJavaが原因です。

用に生成されたバイトコードを確認してくださいequalTest。パラメータとして持つメソッドを呼び出すことがはっきりとわかりObjectます。

this.equals((Object)et)呼び出すのと同じですObject method

// Method descriptor #15 (Ljava/lang/Object;Ljava/lang/Object;)Z
// Signature: <T:Ljava/lang/Object;>(TT;TT;)Z
// Stack: 2, Locals: 2
public static boolean equalTest(java.lang.Object o1, java.lang.Object o2);
0  aload_0 [o1]
1  aload_1 [o2]
2  invokevirtual java.lang.Object.equals(java.lang.Object) : boolean [18]

必要なのは

public static <T extends EqualsTest> boolean equalTest(T o1, T o2) {
    return o1.equals(o2);
}

生成されたバイトコードを確認してみましょう。

public static boolean equalTest(EqualsTest o1, EqualsTest o2);
0  aload_0 [o1]
1  aload_1 [o2]
2  invokevirtual EqualsTest.equals(EqualsTest) : boolean [18]
5  ireturn

ご覧のとおり、コンパイラはObject特定の型に変更されました。これはEqualsTest、これを使用Bounded Typeしたためです。equalTestこれを呼び出すと、次のメソッドが呼び出されます。equalTest as parameter

于 2012-11-05T17:41:01.770 に答える
1

コンパイラは、最も具体的なものではなく、引数の宣言された型に基づいて対応するメソッドを見つけます。@ nicholas.hauschild が正しく指摘しているように、thee には何も指定していないためT、デフォルトはです。Object

于 2012-11-05T17:24:21.653 に答える
1

オーバーロードを使用したため、メソッドはコンパイル時にリンクされ、Java は、この場合はオブジェクトであり EqualsTest ではない呼び出し先へのポリモーフィック バインディングに、特定性の低い引数タイプを使用します。

于 2012-11-05T17:27:11.343 に答える