泛型
泛型用法
泛型的用法是在容器后面添加<Type>
1 | ArrayList<APHero> heros = new ArrayList<APHero>(); |
Type可以是类,抽象类,接口;
泛型表示这种容器,只能存放APHero,ADHero就放不进去了。
创建支持泛型的类
- 设计一个支持泛型的栈 MyStack
- 设计这个类的时候,在类的声明上,加上一个
,表示该类支持泛型。 - T是type的缩写,也可以使用任何其他的合法的变量,比如A,B,X都可以,但是一般约定成俗使用T,代表类型。
1 | package generic; |
通配符
? extends
ArrayList heroList<? extends Hero>
表示这是一个Hero泛型或者其子类泛型(可以理解为这个heroList的元素类型是:Hero或其子类类型):
- heroList 的泛型可能是Hero
- heroList 的泛型可能是APHero
- heroList 的泛型可能是ADHero
所以 可以确定的是,从heroList取出来的对象,一定是可以转型成Hero的
1 | ArrayList<APHero> apHeroList = new ArrayList<APHero>(); |
注:不能往里面放东西,因为:
- 放APHero就不满足<ADHero>
- 放ADHero又不满足<APHero>
1 heroList.add(new ADHero()); //编译错误,因为heroList的泛型有可能是APHero
? super
ArrayList heroList<? super Hero>
表示这是一个Hero或者其父类泛型:
- heroList的泛型可能是Hero
- heroList的泛型可能是Object
可以往里面插入Hero以及Hero的子类:
- 放Hero没问题
- 放APHero、ADHero也没问题
但是取出来有风险,因为不确定取出来是Hero还是Object
1 | ArrayList<? super Hero> heroList = new ArrayList<Object>(); |
1 | //所以就可以插入Hero |
1 | //但是,不能从里面取数据出来,因为其泛型可能是Object,而Object是强转Hero会失败 |
泛型通配符【?】
泛型通配符?
代表任意泛型
既然?代表任意泛型,那么换句话说,这个容器什么泛型都有可能;
- 取:只能以Object的形式取出来
- 放:不能往里面放对象,因为不知道到底是一个什么泛型的容器
1 | ArrayList<APHero> apHeroList = new ArrayList<APHero>(); |
总结
如果希望只取出,不插入,就使用? extends Hero
如果希望只插入,不取出,就使用? super Hero
如果希望,又能插入,又能取出,就不要用通配符?