java 泛型与通配符(?)
泛型应用于泛型类或泛型方法的声明。
如类GenericTest
public class GenericTest<T> { private T item; public void set(T item) { this.item = item; } public T get() { return item; } }
有该类生成对象时可以选择相应的类型,GenericTest<Integer> test = new GenericTest<>(); GenericTest<String> test = new GenericTest<>();
java中比较常见的是容器类,如List<Double> list = new ArrayList<>(),Map<Integer,String> map = new HashMap<>();
通配符(?)应用于泛型的使用
通配符是拿来使用定义好的泛型的,如使用上述泛型类的方法,
public void test(GenericTest<?> obj) { System.out.println(obj); }
如List<?> list = new ArrayList<String>(); 理论上?使list可以添加任何元素,但List<?>这种写法不能向list中添加任何元素(除了null),list.add("abc"); list.add(56); 都会报错。无法确定添加元素的类型,就无法分配内存大小。
较为常见的是<? extends T> 或者 <? super T> 带有边界的通配符。
List<? extends T> 表明list中的元素都是T及T的子类,List<? super T> 表明list中的元素都是T及T的父类。
Integer是Number的子类,但ArrayList<Integer>不是ArrayList<Number>的子类,如下声明是错误的。
ArrayList<Number> list = new ArrayList<Integer>(); // 错误。
但是list中可以添加Integer对象(Number子类对象)。
ArrayList<Number> list = new ArrayList<Number>();
list.add(new Integer(3)); // 正确
改为ArrayList<? extends Number> list = new ArrayList<Integer>(); 也是正确的。
<? extends T>不能往里存,只能向外取。
List<? extends Number> list = new ArrayList<>();
list.add(3); // 错误
list.add(2.2); // 错误
Number n = list.get(0); //正确
float f = (float)list.get(1); //正确
<? super T> 可以向里存,也可以向外取。
List<? super Integer> list = new ArrayList<>();
list.set(0, 2); // 正确
int a = (int)list.get(0); // 正确
posted on 2018-05-04 20:53 Deltadeblog 阅读(226) 评论(0) 编辑 收藏 举报