17

次の例では:

public static void main(String[] args) {

    List<String> b = new ArrayList<String>();
    first(b);
    second(b);

    List<List<String>> a = new ArrayList<List<String>>();
    third(a);
    fourth(a);  // doesnt work

}

private static <T> void first(List<T> a){
    System.out.println("List of T");
}

private static void second(List<?> a){
    System.out.println("List of anything ");
}

private static <T> void third(List<List<T>> a){
    System.out.println("List of a List of T ");
}

private static void fourth(List<List<?>> a){
    System.out.println("List of a List of anything ");
}

second(b) の呼び出しは機能するのに、fourth(a) の呼び出しは機能しないのはなぜですか?

次のエラーが表示されます。

The method fourth(List<List<?>>) in the type `TestTest` is not applicable for the arguments (`List<List<String>>`)
4

5 に答える 5

17

fourth引数付きで呼び出すことができるようにしたい場合はList<List<String>>、署名を次のように変更する必要があります。

private static void fourth(List<? extends List<?>> a){
    System.out.println("List of a List of anything ");
}

List<List<?>>とは異なり、List<? extends List<?>>は と互換性があるため、上記は機能しList<List<String>>ます。次のように考えてください。

List<List<String>> original = null;
List<? extends List<?>> ok  = original; // This works
List<?> ok2                 = original; // So does this
List<List<?>> notOk         = original; // This doesn't

List<Integer> original      = null;
List<? extends Number> ok   = original; // This works
List<?> ok2                 = original; // So does this
List<Number> notOk          = original; // This doesn't

理由は簡単です。もしあなたが持っていたら

private static void fourth(List<List<?>> a) {
    List<?> ohOh = Arrays.asList(new Object());
    a.add(ohOh);
}

そして、そのメソッドをそのように呼び出すことができれば:

List<List<String>> a = new ArrayList<List<String>>();
fourth(a);
String fail = a.get(0).get(0); // ClassCastException here!
于 2012-11-05T10:30:02.290 に答える
5

AList<List<String>>はではありませんList<List<?>>

に関係なく、に何でもList<?>入れることができるはずです。Aは。のみを受け入れます。List<List<?>>?List<List<String>>List<String>

于 2012-11-05T10:26:48.173 に答える
2

これは、型が不明であり、任意の型のオブジェクトを追加でき、コンパイラList<List<?>> はすべてのオブジェクトが同じ型heterogeneousであることを保証できないことを意味します。したがって、バインドされた型をパラメーターとして受け取るList<List<?>>new に渡すことはできません。ArrayList<List<String>>()

于 2012-11-05T10:35:43.287 に答える
1

List<List<String>>と同じではありませんList<List<?>>。ジェネリックは本質的に不変です。で表すことができるので、実行List<?>して渡すだけで機能します。List<String>List of AnythingLists of String

しかし、では表せList of List of anythingませんList of List of String

@Lukas Elder動作するケースをすでに指定しています。これが機能する2番目のケースです

private static void fourth(List<?> a){
    System.out.println("List of anything ");
}
于 2012-11-05T10:27:44.243 に答える
0
List<List<?>> == List {                 //That contains any unknown type lists
                        List<Integer>,
                        List<String>,
                        List<Object>
                      }

一方

List<? extends List<?> == List {       //That contains same unknown type lists
                        List<Integer>,
                        List<Integer>,
                        List<Integer>
                      }

だからここに

 List<List<String>> == List {        //That contains same String lists
                        List<String>,
                        List<String>,
                        List<String>
                      }

したがってList<? extends List<?>、 のスーパー タイプでList<List<String>>あり、割り当て可能です。

fourthメソッドを呼び出すための有効な値は以下のとおりです。

    List<List<?>> a1 =  new ArrayList<List<?>>();
    a1.add(new ArrayList<String>());
    a1.add(new ArrayList<Integer>());
    a1.add(new ArrayList<Object>());
于 2016-06-08T12:25:49.300 に答える