38 泛型的通配符扩展应用
泛型中的?通配符:
l问题:
Ø 定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,该方法如何定义呢?
l错误方式:
public static void printCollection(Collection<Object> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
/* cols.add("string");//没错
cols = new HashSet<Date>();//会报告错误!*/
}
l正确方式:
public static void printCollection(Collection<?> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
//cols.add("string");//错误,因为它不知自己未来匹配就一定是String
cols.size();//没错,此方法与类型参数没有关系
cols = new HashSet<Date>();//没错,使用?通配符可以引用其他各种参数化的类型,
}
l总结:
Ø 使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
Ps:
/*Cols<Object> 中的Object只是说明Cols<Object> 实例对象中的方法接受的参数是Object
Cols<Object> 是一种具体类型,new HashSet<Date>也是一种具体类型,两者没有兼容性问题。
*/
Collection<?> a可以与任意参数化的类型匹配,但到底匹配的是什么类型,只有以后才知道,所以,
a=new ArrayList<Integer>和a=new ArrayList<String>都可以, 但a.add(new Date())或a.add(“abc”)都不行,
泛型中的?通配符的扩展:
l 限定通配符的上边界:
Ø 正确:Vector<? extends Number> x = new Vector<Integer>();
Ø 错误:Vector<? extends Number> x = new Vector<String>();
l 限定通配符的下边界:
Ø 正确:Vector<? super Integer> x = new Vector<Number>();
Ø 错误:Vector<? super Integer> x = new Vector<Byte>();
l 提示:
Ø 限定通配符总是包括自己。
Ø 只能用作引用,不能用它去给其他变量赋值
Vector<? extends Number> y = new Vector<Integer>();
Vector<Number> x = y;
上面的代码错误,原理与Vector<Object > x11 = new Vector<String>();相似,
只能通过强制类型转换方式来赋值。
39 泛型集合的综合应用案例
l 能写出下面的代码即代表掌握了Java的泛型集合类:
HashMap<String,Integer> hm = new HashMap<String,Integer>();
hm.put("zxx",19);
hm.put("lis",18);
Set<Map.Entry<String,Integer>> mes= hm.entrySet();
for(Map.Entry<String,Integer> me : mes) {
System.out.println(me.getKey() + ":" + me.getValue());
}
l 对在jsp页面中也经常要对Set或Map集合进行迭代:
<c:forEach items=“${map}” var=“entry”>
${entry.key}:${entry.value}
</c:forEach>
代码:
HashMap<String, Integer> maps=new HashMap<String, Integer>(); maps.put("a", 1); maps.put("b", 1); maps.put("c", 1); Set<Map.Entry<String, Integer>> entrySet=maps.entrySet(); for (Map.Entry<String, Integer> entry : entrySet) { System.out.println(entry.getKey()+":"+entry.getValue()); }