实现仅包含一个接口的接口时有两种方法

我创建了界面。源代码:TwoMethods

interface TwoMethods<T>
{
    public void method(T t);
}

然后我创建了实现此接口的类,在反汇编后,我看到了2种方法。类:

class A implements TwoMethods<A>
{
    @Override
    public void method(A a) {}
}

拆卸后:

class A implements TwoMethods<A> {
   A();
   public void method(A); //first
   public void method(java.lang.Object); //second
}

接口也是如此。为什么当我创建参数化接口时,我有2种方法。它总是,当我使用参数?我有额外的方法与作为参数?ComparableObject


答案 1

method(java.lang.Object)它被称为 bridge 方法,它是由于编译时的类型擦除而生成的。

请参见类型擦除和桥接方法的影响


答案 2

如果我们看一下接口 TwoMethods 字节码,我们会发现实际的方法

public abstract method(Ljava/lang/Object;)V

即在字节码级别,有关类型参数的信息不存在,类型被擦除,JVM 根本不知道泛型,类型参数被替换为 或如果替换为 .所以从JVM的角度来看ObjectT extends XX

class A implements TwoMethods<A> {
    public void method(A a) {
        ...

method(A a)不覆盖接口方法,因为在字节码中,它所在的接口方法可以覆盖它。为了解决这个问题,编译器在类A中构建了一个隐式方法,即所谓的桥接方法。method(Object obj)

public void method(Object obj) {
     method((A)obj);
}

仅在字节码中可见。现在对于此代码

A a = new A();
TwoMethods<A> tm = a;
tm.method(a);

编译器将替换为对桥接的调用tm.method(a)

   INVOKEINTERFACE test/TwoMethods.method(Ljava/lang/Object;)V

这会将调用重定向到A.method(A a);