Java自学-泛型 通配符
Java 泛型通配符 ? extends super 的用法
示例 1 : ? extends
ArrayList heroList<? extends Hero> 表示这是一个Hero泛型或者其子类泛型
heroList 的泛型可能是Hero
heroList 的泛型可能是APHero
heroList 的泛型可能是ADHero
所以 可以确凿的是,从heroList取出来的对象,一定是可以转型成Hero的
但是,不能往里面放东西,因为
放APHero就不满足
放ADHero又不满足

package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<APHero> apHeroList = new ArrayList<APHero>();
apHeroList.add(new APHero());
ArrayList<? extends Hero> heroList = apHeroList;
//? extends Hero 表示这是一个Hero泛型的子类泛型
//heroList 的泛型可以是Hero
//heroList 的泛型可以使APHero
//heroList 的泛型可以使ADHero
//可以确凿的是,从heroList取出来的对象,一定是可以转型成Hero的
Hero h= heroList.get(0);
//但是,不能往里面放东西
heroList.add(new ADHero()); //编译错误,因为heroList的泛型 有可能是APHero
}
}
示例 2 : ? super
ArrayList heroList<? super Hero> 表示这是一个Hero泛型或者其父类泛型
heroList的泛型可能是Hero
heroList的泛型可能是Object
可以往里面插入Hero以及Hero的子类
但是取出来有风险,因为不确定取出来是Hero还是Object

package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<? super Hero> heroList = new ArrayList<Object>();
//? super Hero 表示 heroList的泛型是Hero或者其父类泛型
//heroList 的泛型可以是Hero
//heroList 的泛型可以是Object
//所以就可以插入Hero
heroList.add(new Hero());
//也可以插入Hero的子类
heroList.add(new APHero());
heroList.add(new ADHero());
//但是,不能从里面取数据出来,因为其泛型可能是Object,而Object是强转Hero会失败
Hero h= heroList.get(0);
}
}
示例 3 : 泛型通配符?
泛型通配符? 代表任意泛型
既然?代表任意泛型,那么换句话说,这个容器什么泛型都有可能
所以只能以Object的形式取出来
并且不能往里面放对象,因为不知道到底是一个什么泛型的容器

package generic;
import java.util.ArrayList;
import property.Item;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<APHero> apHeroList = new ArrayList<APHero>();
//?泛型通配符,表示任意泛型
ArrayList<?> generalList = apHeroList;
//?的缺陷1: 既然?代表任意泛型,那么换句话说,你就不知道这个容器里面是什么类型
//所以只能以Object的形式取出来
Object o = generalList.get(0);
//?的缺陷2: 既然?代表任意泛型,那么既有可能是Hero,也有可能是Item
//所以,放哪种对象进去,都有风险,结果就什么什么类型的对象,都不能放进去
generalList.add(new Item()); //编译错误 因为?代表任意泛型,很有可能不是Item
generalList.add(new Hero()); //编译错误 因为?代表任意泛型,很有可能不是Hero
generalList.add(new APHero()); //编译错误 因为?代表任意泛型,很有可能不是APHero
}
}
示例 4 : 总结
如果希望只取出,不插入,就使用? extends Hero
如果希望只插入,不取出,就使用? super Hero
如果希望,又能插入,又能取出,就不要用通配符?
练习: extends
如代码所示,为了遍历不同泛型的3种集合,需要设计3个方法
借助? extends, 把代码减肥到只是用一种方法
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void iterate(ArrayList<Hero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void iterateAP(ArrayList<APHero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void iterateAD(ArrayList<ADHero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void main(String[] args) {
ArrayList<Hero> hs = new ArrayList<>();
ArrayList<APHero> aphs = new ArrayList<>();
ArrayList<ADHero> adhs = new ArrayList<>();
iterate(hs);
iterateAP(aphs);
iterateAD(adhs);
}
}
答案:
使用一个方法:
public static void iterate(ArrayList<? extends Hero> list) {
}
就表示传递进去的集合的泛型可以是Hero的子类
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void iterate(ArrayList<? extends Hero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void main(String[] args) {
ArrayList<Hero> hs = new ArrayList<>();
ArrayList<APHero> aphs = new ArrayList<>();
ArrayList<ADHero> adhs = new ArrayList<>();
iterate(hs);
iterate(aphs);
iterate(adhs);
}
}
Java自学-泛型 通配符的更多相关文章
- Java 之泛型通配符 ? extends T 与 ? super T 解惑
简述 大家在平时的工作学习中, 肯定会见过不少如下的语句: List<? super T> List<? extends T> 我们都知道, 上面的代码时关于 Java 泛型的 ...
- Java中泛型通配符的一点概念
以List<T>为例,通常如果我们想在List中存储某种类型的数据,我们会用下面的语法进行声明和使用: List<String> allMsg = new ArrayList& ...
- Java自学-泛型 泛型转型
Java 中的子类泛型转型成父类泛型 步骤 1 : 对象转型 根据面向对象学习的知识,子类转父类 是一定可以成功的 package generic; import charactor.ADHero; ...
- 【Java】java 中的泛型通配符——从“偷偷地”地改变集合元素说起
一直没注意这方面的内容,想来这也算是基础了,就写了这个笔记. 首先java的通配符共有三种----先别紧张,现在只是粗略的过一下,看不看其实无所谓 类型 介绍 <?> 无限定通配符,等价于 ...
- Java 泛型 通配符类型
Java 泛型 通配符类型 @author ixenos 摘要:限定通配符类型.无限定通配符类型.与普通泛型区别.通配符捕获 通配符类型 通配符的子类型限定(?都是儿孙) <? extends ...
- -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器
集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别? A:长度区别 ...
- [转]JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...
- java泛型---通配符,泛型嵌套
package generic; import java.util.ArrayList; import java.util.List; /** * ? -->通配符,类型不确定,用于声明 变量| ...
- Java那些事-泛型通配符
Java的类型通配符,可以出现在类.方法上面.最常用的方式就是集合类,例如List,Set等类上面. 通配符类型 有泛型参数 List 有无类型标识 List< ? > 有通用的标识 Li ...
随机推荐
- UVA - 818 Cutting Chains(切断圆环链)(dfs + 二进制法枚举子集)
题意:有n个圆环(n<=15),已知已经扣在一起的圆环,现在需要打开尽量少的圆环,使所有圆环可以组成一条链. 分析:因为不知道要打开哪个环,如果列举所有的可能性,即枚举打开环的所有子集,最多才2 ...
- UVA - 10003 Cutting Sticks(切木棍)(dp)
题意:有一根长度为L(L<1000)的棍子,还有n(n < 50)个切割点的位置(按照从小到大排列).你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小.每次切割的费用 ...
- POJ 2481:Cows 树状数组
Cows Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 14906 Accepted: 4941 Description ...
- 用AD 输出BOM时提示failed to open excel template
解决办法: 去掉这个√!
- 字符,字符串,int之间互相转换
字符转换成字符串:String str = String.valueOf(ch); 字符转换成int: int a = ch; 字符串转换成字符:char ch = str.charAt(0); 字符 ...
- SQL COOKBOOK SQL经典实例代码 笔记第一章代码
-- SQL COOKBOOK CHAPTER1 -- 查看所有内容 select * from emp; -- 可以单列 select empno,ename,job,sal,mgr,hiredat ...
- PAT A1015-1016
A 1015 Reversible Primes 看清题意即可.给的数是十进制的,需要先判断是不是素数,然后按照给定进制转化成字符串后进行翻转,最后再转化为十进制并判断是否为素数. #include ...
- 2020/2/3 PHP代码审计之PHP弱类型
0x00 简介 php中有两种比较的符号 == 与 === <?php 2 $a = $b ; 3 $a===$b ; 4 ?> === 在进行比较的时候,会先判断两种字符串的类型是否相等 ...
- 常用函数式接口与Stream API简单讲解
常用函数式接口与Stream API简单讲解 Stream简直不要太好使啊!!! 常用函数式接口 Supplier<T>,主要方法:T get(),这是一个生产者,可以提供一个T对象. C ...
- ES6的一些语法
let, const, class, extends, super, arrow functions, template string, destructuring, default, rest ar ...