1

ラッパーのファクトリ メソッドを作成しようとしていますが、ジェネリック型につまずいています。

私は 2 つのクラス A と B を持っており、B は A から派生しています。次に、A と B の Wrappber 基本クラス (WBase) とラ​​ッパー クラス WA と WB を持っています。

以下のコードをコンパイルすると、

型の安全性: 型 Test のジェネリック メソッド wrap(Class, T) の未チェックの呼び出し wrap(Class, Test.B)

ラップメソッドの呼び出しに関する警告? それを正しく行う方法はありますか?

乾杯

public class Test {

    public class A {
    }

    public class B extends A {
    }

    public class WBase<T> {
    }

    public class WA<T extends A> extends WBase<T> {
    }

    public class WB extends WA<B> {
    }

    public <T, W extends WBase<T>> W wrap(Class<W> cls, T item) {
        return null;
    }

    public void test() {
        B b = new B();
        wrap(WA.class, b);
    }
}

アップデート:

私はちょうど私の問題を解決しました!:-) 私が見つけた解決策は、追加のラッパー クラス WABase を導入し、WA をそのクラスから拡張させ、WA からジェネリック パラメータを削除することです。

public class WABase<T extends A> extends WBase<T> {} 
public class WA extends WBase<A> {} 
public class WB extends WABase<B> {} 

さらに、wrap メソッドを次のように再定義しました。

<T, W extends WBase<? super T>> W wrap(Class<W> cls, T item) 

今ではすべて正常に動作します:

B b = new B(); 
A a = new A(); 
wrap(WB.class, b); 
// wrap(WB.class, a); // does not compile, which is right 
wrap(WA.class, a); 
wrap(WA.class, b);

私を正しい方向に導いてくれた morgano と newacct に感謝します。

4

3 に答える 3

1

問題はこの部分にあります:

wrap(WA.class, b)

WA はパラメーター化されたクラスです。WA.classを使用する場合、「生の」型を使用しています。

于 2013-06-30T11:22:10.030 に答える
0

bタイプは であるためBwrap(WA.class, b)呼び出しTではBです。Tisであるため、最初の引数として渡されBたインスタンスの型付き変数は拡張する必要があります。の型付き変数 isは明らかに拡張されています。ClassWBase<B>WA.classWAWBase<T>

しかし、Tインはインでpublic class WA<T extends A> extends WBase<T> はありませんTpublic <T, W extends WBase<T>> W wrap(Class<W> cls, T item)。これらは 2 つの独立したTです。Ts の1 つを、たとえば で切り替えると、Sまだコンパイルできることがわかります。

于 2013-06-30T11:26:41.870 に答える