实现只包含一个接口的两种方法

时间:2013-12-25 10:48:15

标签: java generics interface type-erasure java-bridge-method

我创建了界面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
}

同样适用于Comparable接口。为什么当我创建参数化接口时,我有两种方法。总是,当我使用参数时?我还有Object作为参数的方法吗?

2 个答案:

答案 0 :(得分:18)

method(java.lang.Object)被称为桥接方法,它是在编译时因类型擦除而生成的。

请参阅Effects of Type Erasure and Bridge Methods

答案 1 :(得分:15)

如果我们查看接口TwoMethods字节码,我们将看到实际的方法是

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

在类型参数的字节码级别信息不存在,类型被删除,JVM根本不知道泛型,类型参数用Object替换,或者如果T extends X替换{ {1}}。所以从JVM的角度来看

X

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