5

AクラスBが実装するインターフェースがあります。

次の一般的な方法が機能します

public static <T, U extends T> List<T> listFactory(Collection<U> source) {
    return new ArrayList<T>(source);
}

しかし

public static <T> List<T> listFactory(Collection<? extends T> source) {
    return new ArrayList<T>(source);
}

私が出力をに向けているとき、しません(コンパイルエラー、タイプの不一致)

List<A> tester = listFactory(B.defaultCollectionFactory(3));

defaultCollectionFactory(int count)Bデフォルトのラベル付けスキームを使用して、sのコレクションを静的に提供します。

それがなぜであるかについての洞察はありますか?一般的なUとワイルドカードは同じことをしているようです。

4

2 に答える 2

4

コンパイラーは、listFactoryメソッドに対して予想とは異なる型パラメーターを推測しています。それTはタイプBであると推測するので、署名は事実上List<B> listFactory(Collection<? extends B> source)です。Aメソッド呼び出しで明示的に型パラメーターを指定します。

List<A> tester = Test.<A> listFactory(B.defaultCollectionFactory(3));
于 2009-10-03T19:34:27.440 に答える
2

最初の構成では、List渡されたアイテムのインターフェースのを返すことを指定しています。渡されたオブジェクトと U extends T方向の戻りオブジェクトタイプとの関係を指定します。この場合、コンパイラーはとをAそれぞれBに関連付けることができます。TU

2番目の例では、そのような区別がないため、コンパイラーは、がをT参照しB、戻り値をとして入力すると想定しますList<B>B次に、のインスタンスであるが、のインスタンスでAList<B>ないトラップに陥りますList<A>。コンパイラは文句を言います:

タイプの不一致:List<B>からList<A>に変換できません

List最初の構成では、実装するインターフェイスBまたはB階層内のスーパークラス(List<Object>たとえば)を自由に指定でき、コンパイラは文句を言わないことがわかります。

于 2009-10-03T19:27:25.567 に答える