一. 在集合中使用泛型
- 在集合中没有使用泛型的情况下
List list = new ArrayList();
list.add(123);
list.add(321);
list.add(987);
// 没有使用泛型, 任何object及其子类都可以添加进来
list.add("abc");
for (Object o : list) {
// 强转为int类型时, 可能会报 ClassCastException异常
int i = (int)o;
System.out.println(i);
}
- 在集合中使用泛型的情况下
List<Integer> list = new ArrayList();
list.add(123);
list.add(321);
list.add(987);
for (Integer integer : list) {
System.out.println(integer);
}
Map<String, Integer> map = new HashMap<>();
map.put("a", 111);
map.put("b", 222);
map.put("c", 333);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + entry.getValue());
}
二. 自定义泛型类、泛型接口、泛型方法
自定义泛型类
1. 当实例化泛型类的对象时, 需要指明泛型的类型. 对应的类中所有使用泛型的位置, 都变为实例化中指定的类型
2. 如果我们自定义了泛型类, 但是在实例化时没有使用, 那么默认类型是Object类
3. 继承泛型类或泛型接口时, 可以指明泛型的类型
public class GenericityBean<T> {
private T t;
List<T> list = new ArrayList();
public void add(){
list.add(t);
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
@Override
public String toString() {
return "GenericityBean{" +
"t=" + t +
", list=" + list +
'}';
}
}
public static void main(String[] args) {
GenericityBean<Boolean> bean = new GenericityBean<>();
bean.setT(true);
System.out.println(bean.getT()); // print true
bean.add();
List<Boolean> list = bean.list;
System.out.println(list); // print [true]
}
泛型接口: 与定义泛型类类似
泛型方法:
1. 当通过对象调用泛型方法时, 指明泛型方法的类型
public <T>T getT(T t){
return t;
}
三. 泛型与继承的关系
若类A是类B的子类, 但是List<A>可不是List<B>的子接口
四. 通配符
通配符 ?
List<A>、List<B> 都是List<?>的子类
? extends A : 可以存放A及其子类
? super A : 可以存放A及其父类
可以读取声明为统配符的集合类的对象, 不允许向声明为通配符的结合类中写入对象(唯一例外的是null)
五. 对于泛型类(含集合类)
1. 不可以在static中使用泛型的声明
2. 如果泛型类是一个接口或抽象类, 则不可以创建泛型类的对象
3. 不能再catch中使用泛型
4. 从泛型类派生子类, 泛型类型需要具体化