Java 高级特性 泛型

141 阅读2分钟

一. 在集合中使用泛型

  1. 在集合中没有使用泛型的情况下
        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);
        }
  1. 在集合中使用泛型的情况下
	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. 从泛型类派生子类, 泛型类型需要具体化