通配符在泛型中的应用
先定义类
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、泛型中的?通配符
如果定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,如果这样写
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- publicclass GernericTest {
- publicstaticvoid main(String[] args) throws Exception{
- List<Integer> listInteger =new ArrayList<Integer>();
- List<String> listString =new ArrayList<String>();
- printCollection(listInteger);
- printCollection(listString);
- }
- publicstaticvoid printCollection(Collection<Object> collection){
- for(Object obj:collection){
- System.out.println(obj);
- }
- }
- }
语句printCollection(listInteger);报错
The method printCollection(Collection<Object>) in the type GernericTest is not applicable for the arguments (List<Integer>)
这是因为泛型的参数是不考虑继承关系就直接报错。
这就得用?通配符
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- publicclass GernericTest {
- publicstaticvoid main(String[] args) throws Exception{
- List<Integer> listInteger =new ArrayList<Integer>();
- List<String> listString =new ArrayList<String>();
- printCollection(listInteger);
- printCollection(listString);
- }
- publicstaticvoid printCollection(Collection<?> collection){
- for(Object obj:collection){
- System.out.println(obj);
- }
- }
- }
在方法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>();//这是错误的
提示:限定通配符总是包括自己
通配符在泛型中的应用相关推荐
- java 泛型 class t_java 泛型中classT 和T的区别是什么?
public boolean edit(T entity) 和public T get(Class c, Serializable id)中这两种参数的定义和调用有什么区别? public boole ...
- 聊一聊Java 泛型中的通配符 T,E,K,V,?
点击上方"方志朋",选择"设为星标" 回复"1024"获取独家整理的学习资料 作者:glmapper juejin.im/post/5d57 ...
- 聊一聊-JAVA 泛型中的通配符 T,E,K,V,?
前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据 ...
- Java编程的逻辑 (36) - 泛型 (中) - 解析通配符
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
- JAVA 泛型中的通配符 T,E,K,V,?
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源:8rr.co/2Xqx 前言 Java 泛型(generic ...
- 一文读懂Java泛型中的通配符 ?
之前不太明白泛型中通配符"?"的含义,直到我在网上发现了Jakob Jenkov的一篇文章,觉得很不错,所以翻译过来,大家也可以点击文末左下角的阅读原文看英文版的原文. 下面是我的 ...
- 原神一面:Java 泛型中的通配符 T,E,K,V,?,你确定都了解吗?
点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Sometimes, the same thing, we can ...
- Java 泛型中的通配符详解
目录 1.如何定义和使用上界通配符? 2.如何定义和使用无界通配符? 3.如何定义和使用下界通配符? 4.如何使用通配符定义泛型类或接口之间的子类型关系? 5.通配符的捕获和辅助方法 6.通配符使用指 ...
- Java泛型专题之2、聊一聊-JAVA 泛型中的通配符 T,E,K,V,?
目录 1. 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说 ...
最新文章
- Windows7-win10开启IPv6亲测最有效方法
- 电信在线防杀毒墙,到底是不是流氓软件
- Codeforces Round #670 (Div. 2)
- Oracle public view,【易错概念】以太坊Solidity函数的external/internal,public/private,view/pure/payable区别...
- JS调用CS里的方法:PageMethods
- 【python科学计算发行版】
- kafka的延迟操作-pull操作详解
- Mybatis中insert之后返回主键
- 【QT学习】搭建环境+hello world
- thymealf 高级用法_mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存...
- 函数论_E.C.Tichmarsh_Page 4 级数一致收敛的魏尔斯特拉斯 M-判别法 的推广
- 可编程的,协议独立的软件交换机(论文阅读)
- excel怎么一个格子斜分_excel如何在单元格里加上斜线分割内容
- HTTP/HTPPS协议
- Java初学01:学习路线,Java程序员最新职业规划
- 关于通过前端xslx解析excel日期少一天原因
- 无线网络技术复习整理——第二章
- 石墨文档代码学习笔记分享
- 盒须图 python_什么是盒须图?
- 心通达OA系统的研发源自2001年,距今已有21年的历史沉淀
热门文章
- android-ultra-pull-to-refresh list,[Android]Ultra-Pull-To-Refresh之listview下拉刷新、上拉加载的用例...
- activiti根据当前节点获取下一个UseTask节点
- 二十六、深入Node.js中的文件系统fs模块
- 三十七、细说Scrapy中的settings设置
- 聚焦视频文本检索:一文概览视频文本检索任务最新研究进展
- 直播 | 复旦大学许燚:少量标注样本场景下基于数据编程的半监督分类
- KDD 2021 | 异质图神经网络的可微元图搜索
- 多篇顶会论文看DRO (Distributionally Robust Optimization) 最新进展
- 近期知识图谱顶会论文推荐,你都读过哪几篇?
- java.exe 安装程序_java实现可安装的exe程序实例详解