?:在实例化对象的时候,不确定泛型参数的具体类型时,可以使用通配符进行对象定义。
(1)?表示通配符,通配符 与 T 的区别
T:作用于模板上,用于将数据类型进行参数化,不能用于实例化对象。
public <T extends Number> void test(T t){
t.byteValue();
}
再如将key,value的数据类型进行< K, V >参数化,而不可以使用通配符
public class Container<K extends Number, V> { // 不能使用<K super Number>这样进行类型参数化
private K key;
private V value;
public Container(K k, V v) {
key = k;
value = v;
}
}
(2)<? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”,只取不放,因为如果有以下代码,我们并不知道这个水果盘子的具体盘子类型(new Plate<Apple>())。
Plate<? extends Fruit> p=new Plate<Apple>();
注意与class Plate<T extends Fruit>的区别。

(3)<? super T>:是指 “下界通配符(Lower Bounds Wildcards)”,可以放,因为水果盘子肯定可以放入苹果,但是取时只能以Object接收。

注意:
(1)一定要区别出?与T的区别,如class ClassName<T extends Number>{}与ClassName<? extends Number>的区别。
(2)对于类型参数化时只能使用extends关键字,而不能使用super
(3)只有类型参数化时才能有如<T extends C1&I1&I2>的形式,而通配符类型不允许有这样的写法。
(4)泛型擦除只针对类型参数化,与通配符没有任何关系
使用通配符后的类型有contravariant性质,contravariant参考:http://www.cnblogs.com/extjs4/p/6305654.html

对于通配符和泛型之间有Capture Conversion,具体可以参考:http://www.cnblogs.com/extjs4/p/6284620.html
另外对于泛型还有类型推断、对于通配符还有类型捕获
参考文章:
(1)https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
(2)http://bayou.io/draft/Capturing_Wildcards.html
(3)http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html 非常重要的文档
本文深入探讨Java中的泛型与通配符概念,包括T与?的区别,上界通配符与下界通配符的用法,以及它们在实例化对象和类型参数化中的角色。同时,讲解了泛型擦除、类型推断和类型捕获等高级主题。
2万+

被折叠的 条评论
为什么被折叠?



