比较器两个比较方法与反射

hin*_*nks 4 java generics reflection

我试图修复一个未知比较器的问题(没有源访问).所以我写了一些反射代码来查看比较器接受的类型.

令人惊讶的是,Reflection告诉我,有两个比较方法,一个是真实类型,另一个是Object:

Comparator<Integer> comp = new Comparator<Integer>()
{

    @Override
    public int compare(Integer o1, Integer o2)
    {
        return 0;
    }
};

Method[] methods = comp.getClass().getMethods();
for (Method method : methods)
{
    if(method.getName().equals("compare")){
        System.out.println(method);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

public int de.hinneLinks.stackoverflow.MyClass$1.compare(java.lang.Integer,java.lang.Integer)
public int de.hinneLinks.stackoverflow.MyClass$1.compare(java.lang.Object,java.lang.Object)
Run Code Online (Sandbox Code Playgroud)

第二种compare方法来自哪里?

但它不可用,为什么?:

comp.compare(1, 2); //Compiles
comp.compare((Object)1,(Object)2); //Does not Compile
Run Code Online (Sandbox Code Playgroud)

然而,我可以用反射调用那些方法,如果我同时调用两个方法new Object(),我会得到两个不同的异常:

compare(java.lang.Object,java.lang.Object)
java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.Integer

compare(java.lang.Integer,java.lang.Integer)
java.lang.IllegalArgumentException: argument type mismatch
Run Code Online (Sandbox Code Playgroud)

如果使用Object定义我的Comparator,那么只有一个Method.

man*_*uti 6

另一个方法(compare(Object obj1, Object2)是编译器生成的桥接方法,用于在类型擦除后保留二进制兼容性:

在编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建一个称为桥接方法的合成方法,作为类型擦除过程的一部分.您通常不需要担心桥接方法,但如果出现在堆栈跟踪中,您可能会感到困惑.

您可以添加对方法的检查以查看它是否是桥接方法:

for (Method method : methods) {
    if (method.getName().equals("compare") && !method.isBridge()) {
        System.out.println(method);
    }
}
Run Code Online (Sandbox Code Playgroud)