Java泛型,未绑定的通配符<?> vs <Object>

Aet*_*tos 13 java generics wildcard

我已经阅读了一些主题,其中涵盖了关于泛型的某些问题,例如它们与原始类型关系.但是我想对Java SE教程中关于未绑定泛型的某一行进行补充说明.

根据一句话:

printList的目标是打印任何类型的列表,但它无法实现该目标 - 它只打印一个Object实例列表; 它不能打印List <Integer>,List <String>,List <Double>等,因为它们不是List <Object>的子类型.

如果我理解这句话; 之间的区别List<?>List<Object>,就是我们可以使用的类型参数List<String>List<Integer>通过实施前.如果我们实现后者,我们只能使用type参数List<Object>.好像List<?>是一个上界ObjectList<? Object>.

但是后面的句子让我感到困惑,因为根据我之前的理解,它List<Object>应该只包含类的实例Object而不包含其他内容.

重要的是要注意List<Object>并且List<?>不一样.您可以将Object或Object的任何子类型插入到List<Object>.但是你只能插入null一个List<?>.

Rob*_*gam 19

这里有两个不同的问题.一个List<Object>像你说的,其实可以采取任何对象.A 至少List<Number>可以采用对象,当然也可以采用任何子类. NumberInteger

但是这样的方法:

public void print(List<Number> list);
Run Code Online (Sandbox Code Playgroud)

实际上将需要List正好 List<Number>.它不会采用任何声明的列表List<Integer>.

所以,不同的是List<?>将采取与任何声明的任何名单,但List<Object>取东西,被宣布List<Object>,没有别的.

最后一个引用只是说明,这List<?>是一个列表,你实际上不知道它的项目是什么类型.因此,除了以外,你不能添加任何东西null.

  • `名单<?extends Number>`将任何*声明*的列表至少为Number,所以需要`List <Number>`和`List <Integer>` (2认同)

Mat*_*eak 9

令你困惑的句子是试图警告你,虽然List<?>是所有通用列表的超类型,但你不能向List<?>集合添加任何东西.

假设您尝试了以下代码:

private static void addObjectToList1(final List<?> aList, final Object o ) {
    aList.add(o);
}

private static void addObjectToList2(final List<Object> aList, final Object o ) {
    aList.add(o);
}

private static <T> void addObjectToList3(final List<T> aList, final T o ) {
    aList.add(o);
}


public static void main(String[] args) {
    List<String> testList = new ArrayList<String>();
    String s = "Add me!";
    addObjectToList1(testList, s);
    addObjectToList2(testList, s);
    addObjectToList3(testList, s);
}
Run Code Online (Sandbox Code Playgroud)

addObjectToList1不编译,因为除了nulla 之外你不能添加任何东西List<?>.(这就是句子试图告诉你的.)

addObjectToList2编译,但对它的调用main()不编译,因为List<Object>它不是超类型的List<String>.

addObjectToList3编译和调用都有效.这是将元素添加到通用列表的方法.