16

インターフェイスを作成しまし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インターフェイスについても同様です。パラメータ化されたインターフェイスを作成するときに、2 つのメソッドがあるのはなぜですか。パラメータを使用するときは常にですか?Object引数として追加のメソッドがありますか?

4

2 に答える 2

18

method(java.lang.Object)ブリッジメソッドと呼ばれ、コンパイル時の型消去のために生成されます。

型消去とブリッジ メソッドの効果を参照してください。

于 2013-12-25T10:51:12.570 に答える
15

インターフェース TwoMethods バイトコードを見ると、実際のメソッドが

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

つまり、型パラメーターに関するバイトコード レベルの情報が存在しない、型が消去されている、JVM が単にジェネリックについて認識していない、型パラメーターがObjectまたは の場合は に置き換えられT extends XXいる。したがって、JVMの観点から

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

method(A a)バイトコードではそれをオーバーライドできるため、インターフェースメソッドをオーバーライドしませんmethod(Object obj)。この問題を修正するために、コンパイラはクラス A にブリッジ メソッドと呼ばれる暗黙的なメソッドを構築します。

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);

于 2013-12-25T11:14:50.660 に答える