web-dev-qa-db-ja.com

リスト<? MyType>を拡張します

ジェネリックに関するJavaの質問があります。ジェネリックリストを宣言しました。

List<? extends MyType> listOfMyType;

次に、いくつかの方法でインスタンス化して、そのリストにアイテムを追加してみます:

listOfMyType = new ArrayList<MyType>();
listOfMyType.add(myTypeInstance); 

myTypeInstanceMyType型のオブジェクトです。コンパイルされません。それは言います:

タイプList <capture#3-of?のメソッドadd(capture#3-of?extends MyType) extends MyType>は引数に適用されません(MyType)

何か案が?

39
Lancelot

Extendsを使用して「プット」することはできません。 Generics-Get and Put rule を見てください。

32
Surya

考慮してください:

class MySubType extends MyType {
}

List<MySubType> subtypeList = new ArrayList<MySubType>();
List<? extends MyType> list = subtypeList;
list.add(new MyType());
MySubType sub = subtypeList.get(0);

subMyTypeが含まれるようになりましたが、これは非常に間違っています。

26

ワイルドカードキャプチャ構文を使用する必要はなく、単に宣言するだけです。

List<MyType> listOfMytype;

十分なはずです。正確な理由を知りたい場合、 Java Generics Tutorial には、Java Generics。の難解な狂気について知りたいことよりも多くのものがあります。場合。

ワイルドカードキャプチャを使用した追加が機能しない理由については、すべてのケースでコンパイラがMyTypeのサブクラスを正確に決定できないため、コンパイラがエラーを出力するためです。

6
Cameron Pope

同様のスレッドがここにあります: どのように要素をワイルドカードジェネリックコレクションに追加できますか?

ジェネリックがどのように機能するかを理解するには、この例をチェックしてください。

    List<SubFoo> sfoo = new ArrayList<SubFoo>();
    List<Foo> foo;
    List<? extends Foo> tmp;

    tmp = sfoo;
    foo = (List<Foo>) tmp;

問題は、ローカル/メンバー変数用ではなく、関数のシグネチャ用に設計されていることです。

3
zslevi

これが本当に役立つかどうかはわかりませんが、これはSpring Frameworkのジェネリックメソッドを呼び出してジェネリックリストも返したいときに使用しなければならなかったものです:

public <T> List<T> findAll(String tableName,Class<?> table) {
    String sql = "SELECT * FROM "+ tableName ;
    List<?> entities = getSimpleJdbcTemplate().query(sql,
            ParameterizedBeanPropertyRowMapper.newInstance(table));
            return (List<T>) entities;
}

パラメータ化には?を使用する必要があるようですリストにサインインして結果を受け取り、期待される戻り値の型にリストをキャストします。

Iamはまだジェネリック医薬品に魅了されています...

2
will824