具有Object.class参数的Class :: getMethod如何工作?

时间:2020-10-13 14:46:08

标签: java reflection compare

false

打印public static void main(String[] args) throws NoSuchMethodException, SecurityException { Method method = String.class.getMethod("compareTo", Object.class); System.out.println(method); }

public int java.lang.String.compareTo(java.lang.Object)

不编译,因为public static void main(String[] args) throws NoSuchMethodException, SecurityException { "Foo".compareTo(new Object()); }

为什么?

2 个答案:

答案 0 :(得分:1)

String实现Comparable<String>,该方法定义了方法compareTo(T o)

由于类型擦除,该方法实际上在运行时为compareTo(Object o)

无论如何,String将该方法实现为compareTo(String o)

由于具有不同的签名,因此Java编译器会生成一个“合成”“桥”方法来使其起作用,这意味着您最终会:

public interface Comparable {
    public int compareTo(Object o);
}

public class String implements Comparable {
    public int compareTo(String o) {
        ...
    }
    public synthetic bridge int compareTo(Object o) {
        return compareTo((String) o);
    }
}

syntheticbridge当然不是可以放入Java源文件中的实际关键字,但是这些修饰符在运行时出现在反射数据中。

Synthetic 方法是由编译器出于内部原因而生成的,因此它们被视为“隐藏”的,这意味着您无法在Java源文件中看到它们,这就是compareTo(new Object())的原因将不会编译。

但是您可以通过反射看到该方法,但是从此处所示的实现中可以看到,如果您实际上通过反射调用了compareTo(new Object()),那么您将得到一个ClassCastException

答案 1 :(得分:0)

这正是完全的泛型可解决的问题。在编译时,编译器可以使用泛型来告诉您将字符串与对象进行比较将无效。

但是,在运行时,泛型将被删除。因此,您可以根据Object方法的参数将String与Object进行比较。