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只会接受 a 。List<List<?>>?List<List<String>>List<String>

于 2012-11-05T10:26:48.173 回答
2

这意味着该类型是未知的,并且可以将任何类型的对象添加到List<List<?>> 其中,heterogeneous并且编译器不能保证其中的所有对象List<List<?>>都是相同的类型。因此,它不能传递ArrayList<List<String>>()给以有界类型作为参数的 new。

于 2012-11-05T10:35:43.287 回答
1

List<List<String>>不一样List<List<?>>。泛型本质上是不变的。如果您只做List<?>并通过List<String>,那么它将起作用,因为List of Anything可以用Lists of String.

List of List of anything不能用 来表示List of List of String

@Lukas Elder已经指定了可行的案例。这是第二种可行的情况

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 回答