ここで G.myUglyList リストの内容を取得し、それを Outer.send() メソッドに渡したいと思います。これがコンパイラエラーを引き起こす理由がわかりません。? extends Inner は Outer をパラメータ化するタイプです。では、渡されたインナーを拒否するのはなぜですか? タイプではない「? extends Inner」が必要です。
List<Outer<? extends Inner>>
Inner のサブタイプを取得できるように、リストを as として宣言する必要があります。(これがなぜなのかについては、以下の編集を参照してください)
interface Outer<T> {
void send(T message);
}
interface Inner {}
interface Inner2 extends Inner {}
public class G {
List<Outer<? extends Inner>> myUglyList;
void foo() {
Inner xxx = null;
for (Outer<? extends Inner> outer : myUglyList) {
outer.send(xxx); //error
}
}
}
次のエラーが表示されます。
error: method send in interface Outer<T#2> cannot be applied to given types;
required: CAP#1
found: Inner<T#1>
reason: actual argument Inner<T#1> cannot be converted to CAP#1 by method invocation conversion
where T#1,T#2 are type-variables:
T#1 extends Object declared in class G
T#2 extends Object declared in interface Outer
where CAP#1 is a fresh type-variable:
CAP#1 extends Inner<T#1> from capture of ? extends Inner<T#1>
edit : type のリストを作成するだけという回答がたくさんありましたList<Outer<Inner>>
が、それは正しくありません。これを行うと、Inner のサブタイプを追加できなくなります。を追加しようとするOuter<Inner2>
と失敗します。したがって、 list は type でなければなりませんList<Outer<? extends Inner>>
。
interface Inner2 extends Inner {}
class G {
void foo() {
Outer<Inner2> foiled = null;
myUglyList.add(foiled); //this will fail if list is of type List<Outer<Inner>>
Inner xxx = null;
for (Outer<? extends Inner> outer : myUglyList) {
outer.send(xxx); //error
}