一、什么是泛型(Generic)
泛型是JDK5引入的一种参数化类型机制
二、为什么要用泛型
- 将类型检查提前到编译期间
- 避免类型转换(避免出现运行期间ClassCastException)
- 提高代码的复用性(容器类)
三、泛型在Java中的使用
-
泛型类
public class Box<T>{ private T obj; public void setObj(T t){ obj = t; } public T getObj(){ return obj; } } -
泛型接口
public interface Animal<T>{ String makeSound(T t); } -
泛型方法
public<T> void print(T t){ System.out.print(t); }
注意:
- 是否拥有泛型方法,与其所在的类是否是泛型没有任何关系
- 判断一个方法是否是泛型方法,可以看是否有
四、讲讲PESC机制
producer-extens , consumer -super.
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)
五、类型擦除(Type Erasure)
- jvm虚拟机不支持泛型
List<String>和List<Integer>在运行时是相同的类型- 泛型擦除后,重载会产生相同的类型签名,下面代码是不能编译的
public class UseList<T,W>{ void f(List<T> v){} void f(List<W> v){} } - catch语句不能捕获泛型类型的异常,泛型类也不能直接或者间接继承自Throwable
六、泛型的通配符
- ? extend xxx(可以读取数据,不能添加数据)
- ? super xxx(可以添加数据,不能读取数据)
- ?(不确定类型)
七、泛型的限制
- 不支持基本数据类型
- 不能使用static关键字
- 不能使用clone
- 不支持数组
- 不是协变的,
Integer extend Number,List<Integer> 和List<Number>是没有继承关系的 - 不能使用
arg instanceOf T - 不能使用
T var = new T(); - 不能使用
T[] array = new T[10];