先定义类

class A {public void fun() {System.out.println("A");}
}class B extends A {@Overridepublic void fun() {System.out.println("B");}}class C extends B {@Overridepublic void fun() {System.out.println("C");}
}

1. 为什么在泛型中需要通配符?

ArrayList<A> ls = new ArrayList<B>();//compile error

即使A是B的父类,这是因为B的list不是A的list的子类

所以这就需要通配符

2. extends

ArrayList<? extends A> arrlist = new ArrayList<B>();

arrlist可以指定A或者A的子类的ArrayList

但是

arrlist.add(new B());
arrlist.add(new A());

就会有编译错误,这是因为add 的参数是 ? extends A, 是A的子孙类,所以不能传入任何对象。

arrlist.contains(new A());

arrlist.indexOf(new A());

以上两条语句是正确,因为contains和indexOf的参数是Object

A a= arrlist.get(0);//ok, 因为返回的是 ? extends A, 是A或者A的子类,所以可以赋值给类A
B b = arrlist.get(0);//error, 不能保证返回的一定是B或者B的子类

如果这样写:

public class Factory<T> {
}

class part {
public String toString () {
return getClass().getSimpleName();
}
}

class filter extends part {

}

class fuel extends filter {

}

class A extends Factory<part> {

}

class B extends A {

}

class C extends Factory<filter> {

}

List<Factory<? extends A>> ls = new ArrayList<Factory<? extends A>>();

ls.add(new A());
ls.add(new B());
ls.add(new C());

这样写是Ok的

3. super

public static void write(List<? super B> ls) {//ls 要求容器内的元素必须是类B,或者B的父类,所以在add的时候,//只能添加B 或者B的孩子,这是因为不能确保ls的泛化的元素是A,只能确认至少是B,即B是下界ls.add(new B());ls.add(new C());//ls.add(new A());//不能添加A}public static void main(String[] args) {// TODO Auto-generated method stub//List<A> ls = new ArrayList<A>();//okList<B> ls = new ArrayList<B>();//okwrite(ls);for (A a : ls)a.fun();
}

http://blog.csdn.net/lonelyroamer/article/details/7927212

通配符有三种:

1、无限定通配符   形式<?>

2、上边界限定通配符 形式< ? extends Number>    //用Number举例

3、下边界限定通配符    形式< ? super Number>    //用Number举例

1、泛型中的?通配符

如果定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,如果这样写

[java] view plaincopy
  1. import java.util.ArrayList;
  2. import java.util.Collection;
  3. import java.util.List;
  4. publicclass GernericTest {
  5. publicstaticvoid main(String[] args) throws Exception{
  6. List<Integer> listInteger =new ArrayList<Integer>();
  7. List<String> listString =new ArrayList<String>();
  8. printCollection(listInteger);
  9. printCollection(listString);
  10. }
  11. publicstaticvoid printCollection(Collection<Object> collection){
  12. for(Object obj:collection){
  13. System.out.println(obj);
  14. }
  15. }
  16. }

语句printCollection(listInteger);报错

The method printCollection(Collection<Object>) in the type GernericTest is not applicable for the arguments (List<Integer>)

这是因为泛型的参数是不考虑继承关系就直接报错。

这就得用?通配符

[java] view plaincopy
  1. import java.util.ArrayList;
  2. import java.util.Collection;
  3. import java.util.List;
  4. publicclass GernericTest {
  5. publicstaticvoid main(String[] args) throws Exception{
  6. List<Integer> listInteger =new ArrayList<Integer>();
  7. List<String> listString =new ArrayList<String>();
  8. printCollection(listInteger);
  9. printCollection(listString);
  10. }
  11. publicstaticvoid printCollection(Collection<?> collection){
  12. for(Object obj:collection){
  13. System.out.println(obj);
  14. }
  15. }
  16. }

在方法public static void printCollection(Collection<?> collection){}中不能出现与参数类型有关的方法比如collection.add();因为程序调用这个方法的时候传入的参数不知道是什么类型的,但是可以调用与参数类型无关的方法比如collection.size();

总结:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量的主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

2、泛型中的?通配符的扩展

1:界定通配符的上边界

Vector<? extends 类型1> x = new Vector<类型2>();

类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的子类

Vector<? extends Number> x = new Vector<Integer>();//这是正确的

Vector<? extends Number> x = new Vector<String>();//这是错误的

2:界定通配符的下边界

Vector<? super 类型1> x = new Vector<类型2>();

类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的父类

Vector<? super Integer> x = new Vector<Number>();//这是正确的

Vector<? super Integer> x = new Vector<Byte>();//这是错误的

提示:限定通配符总是包括自己

通配符在泛型中的应用相关推荐

  1. java 泛型 class t_java 泛型中classT 和T的区别是什么?

    public boolean edit(T entity) 和public T get(Class c, Serializable id)中这两种参数的定义和调用有什么区别? public boole ...

  2. 聊一聊Java 泛型中的通配符 T,E,K,V,?

    点击上方"方志朋",选择"设为星标" 回复"1024"获取独家整理的学习资料 作者:glmapper juejin.im/post/5d57 ...

  3. 聊一聊-JAVA 泛型中的通配符 T,E,K,V,?

    前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据 ...

  4. Java编程的逻辑 (36) - 泛型 (中) - 解析通配符

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  5. JAVA 泛型中的通配符 T,E,K,V,?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源:8rr.co/2Xqx 前言 Java 泛型(generic ...

  6. 一文读懂Java泛型中的通配符 ?

    之前不太明白泛型中通配符"?"的含义,直到我在网上发现了Jakob Jenkov的一篇文章,觉得很不错,所以翻译过来,大家也可以点击文末左下角的阅读原文看英文版的原文. 下面是我的 ...

  7. 原神一面:Java 泛型中的通配符 T,E,K,V,?,你确定都了解吗?

    点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Sometimes, the same thing, we can ...

  8. Java 泛型中的通配符详解

    目录 1.如何定义和使用上界通配符? 2.如何定义和使用无界通配符? 3.如何定义和使用下界通配符? 4.如何使用通配符定义泛型类或接口之间的子类型关系? 5.通配符的捕获和辅助方法 6.通配符使用指 ...

  9. Java泛型专题之2、聊一聊-JAVA 泛型中的通配符 T,E,K,V,?

    目录 1. 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说 ...

最新文章

  1. Windows7-win10开启IPv6亲测最有效方法
  2. 电信在线防杀毒墙,到底是不是流氓软件
  3. Codeforces Round #670 (Div. 2)
  4. Oracle public view,【易错概念】以太坊Solidity函数的external/internal,public/private,view/pure/payable区别...
  5. JS调用CS里的方法:PageMethods
  6. 【python科学计算发行版】
  7. kafka的延迟操作-pull操作详解
  8. Mybatis中insert之后返回主键
  9. 【QT学习】搭建环境+hello world
  10. thymealf 高级用法_mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存...
  11. 函数论_E.C.Tichmarsh_Page 4 级数一致收敛的魏尔斯特拉斯 M-判别法 的推广
  12. 可编程的,协议独立的软件交换机(论文阅读)
  13. excel怎么一个格子斜分_excel如何在单元格里加上斜线分割内容
  14. HTTP/HTPPS协议
  15. Java初学01:学习路线,Java程序员最新职业规划
  16. 关于通过前端xslx解析excel日期少一天原因
  17. 无线网络技术复习整理——第二章
  18. 石墨文档代码学习笔记分享
  19. 盒须图 python_什么是盒须图?
  20. 心通达OA系统的研发源自2001年,距今已有21年的历史沉淀

热门文章

  1. android-ultra-pull-to-refresh list,[Android]Ultra-Pull-To-Refresh之listview下拉刷新、上拉加载的用例...
  2. activiti根据当前节点获取下一个UseTask节点
  3. 二十六、深入Node.js中的文件系统fs模块
  4. 三十七、细说Scrapy中的settings设置
  5. 聚焦视频文本检索:一文概览视频文本检索任务最新研究进展
  6. 直播 | 复旦大学许燚:少量标注样本场景下基于数据编程的半监督分类
  7. KDD 2021 | 异质图神经网络的可微元图搜索
  8. 多篇顶会论文看DRO (Distributionally Robust Optimization) 最新进展
  9. 近期知识图谱顶会论文推荐,你都读过哪几篇?
  10. java.exe 安装程序_java实现可安装的exe程序实例详解