1

この型変換を正しく機能させるのに問題があります。私の推測では、制限付きの汎用ワイルドカード<?super SomeType>は、インターフェースの実装では機能しません。

// sample class definitions
public interface IFace<T> { ... } 
public class MyClass<T1, T2> { ... }
public class UtilityClass<T> {
    public List<MyClass<T, ? super IFace<T>>> getList() { ... }
}
public class Actor extends SomeObj implements IFace<TypeA> { ... }

// use...
UtilityClass<TypeA> utility = new UtilityClass<TypeA>();
List<MyClass<TypeA, Actor>> list = utility.getList();

Type mismatch: cannot convert from List<MyClass<TypeA, ? super IFace<TypeA>> to List<MyClass<TypeA, Actor>>
4

3 に答える 3

4

JoshuaBlochの効果的なJava第2版を引用:

リターンタイプとしてワイルドカードタイプを使用しないでください。ユーザーに追加の柔軟性を提供するのではなく、クライアントコードでワイルドカードタイプを使用するように強制します。

適切に使用されると、ワイルドカードタイプはクラスのユーザーにはほとんど見えなくなります。それらは、メソッドに、受け入れるべきパラメーターを受け入れさせ、拒否すべきパラメーターを拒否させます。クラスのユーザーがワイルドカードタイプについて考える必要がある場合は、クラスのAPIに問題がある可能性があります

于 2012-01-07T19:31:06.660 に答える
1

ジェネリックを使い始めるとき、本当に必読なのはこのチュートリアルです。4 ページの「ジェネリックとサブタイピング」セクションを読めば、なぜこのエラーが発生するのかがわかります。インターフェイスを使用しているという事実とは何の関係もありません

于 2012-01-07T19:31:35.207 に答える
0

直感的に、メソッドをジェネリックにすることで問題を解決しようとするかもしれません。

public <X super IFace<T>> List<MyClass<T, X> getList() { ... }

ただし、 を使用して型パラメーターに下限を与えることは通常意味がないため、この構文は許可されていませんsuper。理由の詳しい説明については、この記事を参照してください: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

編集:

コードを見ると、型パラメーターの境界を指定する際に混乱superする可能性があると思います。extendsこれの 2 番目の型パラメーターの上限を指定しているため、代わりにgetList()a が返された場合に意味があります(つまり、その型は を実装するものでなければなりません)。 List<MyClass<T, ? extends IFace<T>>>MyClassIFace<T>

natixの回答が指摘しているように、返されたオブジェクトのジェネリック型情報の一部を効果的に隠すため、ジェネリック戻り型でワイルドカードを使用することは推奨されません。代わりに、メソッドをジェネリックにします。

public <X extends IFace<T>> List<MyClass<T, X> getList() { ... }

これにより、呼び出し元のコードがX型推論を通じて型を指定できるようになります。

于 2012-01-07T19:33:54.407 に答える