在下面的代码中,为什么o1.equals(o2);
调用equals(Object o)
而不调用equals(EqualsTest et)
,即使o1
和o2
引用{{1}类型的对象}}!
EqualsTest
答案 0 :(得分:1)
编译器根据declared type of the argument找到相应的方法,而不是最具体的方法。由于您没有为T
指定任何内容,因此默认为Object
,正如@ nicholas.hauschild正确指出的那样。
答案 1 :(得分:1)
由于您已经使用了重载,因此在编译时链接方法,并且Java使用不太具体的参数类型来进行与被调用者的多态绑定,在这种情况下是对象,而不是EqualsTest。
答案 2 :(得分:1)
正如我在评论中提到的,这是因为java中的TypeErasure
。
检查为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
,它将使用{调用方法{1}}