Java泛型:通配符
来源:互联网 发布:p2p网管软件 编辑:程序博客网 时间:2024/04/28 19:41
通配符是Java泛型里的一部分,但是在普通业务代码上应用不会很多,其提供一系列关于编译器上的检查,以保证代码的稳定。这里记录一些这两天学习到的关于通配符的知识。
package com.qpm.learn.base;import java.util.*;/** * @ClassName: UnboundedWildcards1 * @Description: TODO Java泛型学习 * @author kangqiang.w 945766863@qq.com * @date 2017年3月5日 上午9:34:55 * */class Fruit{}class Apple extends Fruit{}class Orange extends Fruit{}public class UnboundedWildcards1 { static List list1; //编译器报未确定类型的warn static List<?> list2; static List<? extends Fruit> list3; //list3 只接受具有Fruit特征的元素 static List<? super Fruit> list4; //列表的处理下界是Fruit static void assign1(List list) { list1 = list; list2 = list; list3 = list; //类型安全warning } static void assign2(List<?> list){ list1 = list; list2 = list;// list3 = list; //可能List是符合要求的,但因为编译器始终无法知道其是否正确,所以直接报了编译错误 } static void assign3(List<? extends Fruit> list) { list1 = list; list2 = list; list3 = list; // 参数类型的限制保证了参数 的正确// list.add(new Apple()); } static void assign4(List<Fruit> list){ list1 = list; list2 = list; list3 = list; // 参数类型的限制保证了参数 的正确 } static void assign5(List<? super Apple> list){ list.add(new Apple()); } public static void main(String[] args) { assign1(new ArrayList()); assign2(new ArrayList()); assign3(new ArrayList()); assign1(new ArrayList<String>()); assign2(new ArrayList<String>());// assign3(new ArrayList<String>()); List<?> wildList = new ArrayList(); wildList = new ArrayList<String>(); assign1(wildList); assign2(wildList);// assign3(wildList); /* * static List<? extends Fruit> list3; //list3 只接受具有Fruit特征的元素 * 这里报编译错误? * 这是一个与常识有所违背的:list3存储的是具有Fruit特征的元素,但是我们不能向List写入继承与Fruit类的Apple对象 * 解:List<? extends Fruit> 意味着:具有任何从Fruit继承的类型的列表。当一个List<Fruit>列表向上转型为List<? extends Fruit>,它将失去向列表传递对象的能力。 * * 应用,一个List<? extends Fruit>的列表居然不能让我们传递具体对象,有什么用呢? * 1、作为一种方法的参数来处理。以List<? extends Fruit>为参数,方法可以接受ArrayList<Apple>或ArrayList<Orange>。 * 假如方法参数是List<Fruit>,那么其只能接受ArrayList<Fruit>的参数类型 * * * */ list3 = new ArrayList<Apple>();// list3.add(new Apple()); List<Fruit> list4 = new ArrayList<Fruit>(); list4.add(new Apple()); list4.add(new Orange()); List<Apple> list5 = new ArrayList<Apple>(); assign3(list5);// assign4(list5); /* * 超类型通配符 * List<? super Fruit>编译器会反应到这个集合处理的必需是一个Fruit, * 如:Apple继承于Fruit,这个变量是不会接受ArrayList<Apple>。因为List<? super Fruit>表示,?的类类型在继承体系中必需高于Fruit。Apple是继承于Fruit,明显是低于Fruit */// list4 = new ArrayList<Apple>(); assign5(new ArrayList<Apple>()); assign5(new ArrayList<Fruit>()); /* * 同上分析: * List<? extend Fruit>具有任何从Fruit继承的类型的列表。 * 相对于List<? super Fruit>而言,extend关键字表达的意思是:?的类类型在继承体系中必需低于Fruit。所以List<? extend Fruit> l = new ArrayList<Apple>()是合法的。 * 为什么List<? extend Fruit>不能够传递任何Apple、Fruit的对象进去呢? * 这与泛型的安全有关,因为编译器至此都无法知道List拥有的是什么类型,所以往这样的list放置对象编译器是不允许的(尽管感觉上没有任何问题),但是相反,从这样的集合获取一个Fruit是允许的, * 因为编译器知道集合里面的对象起码是一个Fruit。 */ System.out.println("finish"); }}
参考资料:《Java编程思想》p389-p396
0 0
- Java泛型-- 通配符
- Java泛型--通配符
- Java泛型-- 通配符
- Java泛型-- 通配符
- Java泛型-- 通配符
- Java泛型:通配符
- [java泛型] 通配符wildcards
- Java泛型 通配符的限定
- java泛型III-通配符
- JAVA通配符
- java通配符
- java 通配符
- Java通配符<?>
- java 通配符
- java 通配符
- java通配符
- java通配符
- Java通配符(?)
- spring boot 使用自定义配置
- JBoss/Wildfly 配置SQLserver服务器
- 【2-5】Python基础——dict和set
- uva 12504 Updating a Dictionary(更新字典)
- 进程间通信之WM_COPYDATA的基本实现
- Java泛型:通配符
- 动态规划:最长上升子序列之基础(经典算法 n^2)
- ext4 设备文件处理
- caffe学习笔记19-batchsize参数
- FRAGMENT
- 怎么使用pipenv管理你的python项目
- Main函数为什么要static
- mybatis自动识别数据库关键字
- Install Xen in a Ubuntu(14.04) server