泛型

关于泛型的几点:

  1. 尖括号里的每个元素都代表一种未知类型
  2. 尖括号只能出现在类名之后(作用于类的泛型)或者方法返回值之前(方法泛型)

使用泛型的好处:

  1. 类型安全 避免粗心导致的类转换异常
  2. 提升代码可读性 编码阶段即可知道对象类型
  3. 提升了代码的复用率

泛型类

class Map<K>{    // 修饰成员变量    private K key;    // 修饰参数    public Map(K key){}    // 修饰返回值    public K get(){        // 修饰局部变量        K key1 = key;        return key1;    }}

泛型方法

// <T> 声明的是这个方法的泛型参数 后面的T声明的是方法的返回类型public static <T> T run(T obj){    return obj;}

泛型限定

// 约定T必须是Comparable的子类<T extends Comparable> // 可同时指定多个父接口<T extends Comparable&Serializable> 

通配符

// 只能接受S的自身或子类<? extends S>// 能接收S自身及其超类<? super S>// 不限制类型,只能使用object接收<?>

PESC原则

Producer Extends Consumer Super

List<Apple> apples = new ArrayList<>();apples.add(new Apple());List<? extends Fruit> basket = apples;//按上一个例子,这个是可行的for (Fruit fruit : basket){    System.out.println(fruit);}//basket.add(new Apple()); //编译错误//basket.add(new Fruit()); //编译错误
List<Apple> apples = new ArrayList<>();apples.add(new Apple());List<? super Apple> basket = apples;//这里使用了superbasket.add(new Apple());basket.add(new RedApple());//basket.add(new Fruit()); //编译错误Object object = basket.get(0);//正确//Fruit fruit =basket.get(0);//编译错误//Apple apple = basket.get(0);//编译错误//RedApple redApple = basket.get(0);//编译错误

出现这个原则的原因是因为 List<Apple>List<Fruit> 没有任何关系

如Java API中对集合的复制:

public static <T> void copy(List<? super T> dest, List<? extends T> src) {  ...}

泛型擦除

补救:

如果想要在运行时获取泛型的类型 那就必须通过某种手段记录泛型的 Class 对象

类型变化关系

批注 2019-10-30 131946