泛型定义中的通配符
含义是:变量foo3可以包含任何继承自Number的类型。
以下都是合法的定义:
因此,考虑到以上可能的定义,什么类型的对象可以被合法的添加到List<? extends Number> foo3中呢?
唯一可以确定的是你可以从List中读取一个Number类型的对象或一个Number类型的子类对象。
相反的逻辑也使用于super,如List<? super T>。一下定义都是合法的:
你不能从List<? super T>中读取一个特定类型的类(如Number),因为你不能确定List真正被定义成什么。(但是可以读取一个Object对象)
唯一可以确定的是你可以向List添加一个T类型的对象或T类型的超类对象。
一个很好的例子是Collection.copy()的定义:
注意src的定义,用extends允许接受任何值为T类型或T类型的子类型的List,并从中读取值,但你不能向src执行添加操作。
dest的定义,用super允许接受任何值为T类型或T类型的超类的List,并向其写入值,但你不能向dest执行读取操作。
由此,感谢泛型通配符,通过如上的一个定义,我们可以做以下这些调用。
下面做一些练习。被注释掉的代码是错误的
List<? extends Number> foo3
含义是:变量foo3可以包含任何继承自Number的类型。
以下都是合法的定义:
List<? extends Number> foo3 = new ArrayList<Number>(); //Number "extends" Number
List<? extends Number> foo3 = new ArrayList<Integer>(); //Integer "extends" Number
List<? extends Number> foo3 = new ArrayList<Double>(); //Double "extends" Number
因此,考虑到以上可能的定义,什么类型的对象可以被合法的添加到List<? extends Number> foo3中呢?
- 你不能添加Integer对象,因为foo3可能被定义为 List<Double>。
- 你不能添加Double对象,因为foo3可能被定义为 List<Integer>。
- 你不能添加Number对象,因为foo3可能被定义为 List<Integer>。
唯一可以确定的是你可以从List中读取一个Number类型的对象或一个Number类型的子类对象。
相反的逻辑也使用于super,如List<? super T>。一下定义都是合法的:
List<? super Number> foo3 = new ArrayList<Number>(); //Number is a "super" of Number
List<? super Number> foo3 = new ArrayList<Object>(); //Object is a "super" of Number
你不能从List<? super T>中读取一个特定类型的类(如Number),因为你不能确定List真正被定义成什么。(但是可以读取一个Object对象)
唯一可以确定的是你可以向List添加一个T类型的对象或T类型的超类对象。
一个很好的例子是Collection.copy()的定义:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
注意src的定义,用extends允许接受任何值为T类型或T类型的子类型的List,并从中读取值,但你不能向src执行添加操作。
dest的定义,用super允许接受任何值为T类型或T类型的超类的List,并向其写入值,但你不能向dest执行读取操作。
由此,感谢泛型通配符,通过如上的一个定义,我们可以做以下这些调用。
//copy(dest, src)
Collection.copy(new ArrayList<Number>(), new ArrayList<Number());
Collection.copy(new ArrayList<Number>(), new ArrayList<Integer());
Collection.copy(new ArrayList<Object>(), new ArrayList<Number>());
Collection.copy(new ArrayList<Object>(), new ArrayList<Double());
下面做一些练习。被注释掉的代码是错误的
List<Number> listNumber_ListNumber = new ArrayList<Number>();
//List<Number> listNumber_ListInteger = new ArrayList<Integer>();
//错误 - 只能接受Number类型。
//List<Number> listNumber_ListDouble = new ArratList<Double>();
//错误 - 只能接受Number类型。
List<Integer> listInteger_ListInteger = new ArrayList<Integer>();
//List<Integer> listInteger_ListDouble = new ArrayList<Double>();
//错误 - 只能接受Integer类型
List<? extends Number> listExtendsNumber_ListNumber = new ArrayList<Number>();
List<? extends Number> listExtendsNumber_ListInteger = new ArrayList<Integer>();
List<? extends Number> listExtendsNumber_ListDouble = new ArrayList<Double>();
List<? extends Integer> listExtendsInteger_ListInteger = new ArrayList<Integer>();
//List<? extends Integer> listExtendsInteger_ListNumber = new ArrayList<Number>();
//错误 - Number不是Integer的子类
//List<? extends Integer> listExtendsInteger_ListDouble = new ArrayList<Double>();
//错误 - Double不是Integer的子类
List<? super Number> listSuperNumber_ListNumber = new ArrayList<Number>();
//List<? super Number> listSuperNumber_ListInteger = new ArrayList<Integer>();
//错误 - Integer不是Number的超类
//List<? super Number> listSuperNumber_ListDouble = new ArrayList<Double>();
//错误 - Double不是Number的超类
//List<Integer> listInteger_ListNumber = new ArrayList<Number>();
//错误 - 只能接受Integer类型
List<? super Integer> listSuperInteger_ListNumber = new ArrayList<Number>();
List<? super Integer> listSuperInteger_ListInteger = new ArrayList<Integer>();
//List<? super Integer> listSuperInteger_ListDouble = new ArrayList<Double>();
//错误 - Double is not a superclass of Integer
listNumber_ListNumber.add(3);
//正确 - 允许添加Integer对象到List<Number>中
//下面的代码将出现编译错误。
//他们有相同的原因:你不知道List<T>真正指向那个类,它也许不能处理Integer。
//所以你不能添加任何类(Object, Number, Integer, Double等)到List<? extends Number>
//listExtendsNumber_ListNumber.add(3);
//错误 - 不能添加Integer,list可能是List<Double>,即使List就是被定义为List<Number>也不行。
//listExtendsNumber_ListInteger.add(3);
//错误 - 不能添加Integer,list可能是List<Double>,即使List就是被定义为List<Integer>也不行。
//listExtendsNumber_ListDouble.add(3);
//错误 - 不能添加Integer,list可能是List<Double>, 特别是List真的是List<Double>。
//listExtendsInteger_ListInteger.add(3);
//错误 - 不能添加Integer,list可能是List<X>,它只接受X类型的对象。
listSuperNumber_ListNumber.add(3);
//正确 - 允许添加Integer到List<Number>或者List<Object>
listInteger_ListInteger.add(3);
//正确 - 允许添加Integer到List<Integer>
listSuperInteger_ListNumber.add(3);
//正确 - 允许添加Integer到List<Integer>, List<Number>或List<Object>
listSuperInteger_ListInteger.add(3);
//正确 - 允许添加Integer到List<Integer>, List<Number>或List<Object>
总结:
参数和返回类型是:List<Foo>
1、可以作为参数传递给List方法的类型:
1、可以作为参数传递给List方法的类型:
参数和返回类型是:List< ? super Foo>
1、可以作为参数传递给List方法的类型:
1、可以作为参数传递给List方法的类型:
- List< Foo>
- List< Foo>
- List< ? super Foo>
- List< ? super SubFoo>
- List< ? extends Foo>
- List< ? extends SuperFoo>
- Foo & subtypes
- Foo & supertypes (up to Object)
1、可以作为参数传递给List方法的类型:
- List< Foo>
- List< Subfoo>
- List< SubSubFoo>
- List< ? extends Foo>
- List< ? extends SubFoo>
- List< ? extends SubSubFoo>
- List< ? extends Foo>
- List< ? extends SuperFoo>
- List< ? extends SuperSuperFoo>
- None! Not possible to add.
- Foo & supertypes (up to Object)
参数和返回类型是:List< ? super Foo>
1、可以作为参数传递给List方法的类型:
- List< Foo>
- List< Superfoo>
- List< SuperSuperFoo>
- List< ? super Foo>
- List< ? super SuperFoo>
- List< ? super SuperSuperFoo>
- List< ? super Foo>
- List< ? super SubFoo>
- List< ? super SubSubFoo>
- Foo & supertypes
- Object