一、泛型定义:是指参数化类型的能力
二、泛型的主要优势是能够在编译时而不是在运行时发现错误
三、泛型使用场景
#1、泛型类
public class Stack<E> {
private List<E> list = new ArrayList<E>();
public int getSize(){
return list.size();
}
public E peek(){
return list.get(getSize()-1);
}
}
#2、泛型接口
public interface Comparable<T> {
public int compareTo(T o);
}
#3、泛型方法
public static <E extends Comparable> boolean equal(E e1, E e2){
return e1.equals(e2);
}
四、通配泛型
#1、 “?” 称为非受限通配 ,等价于 “?extends Object”
#2、“?extends T” 称为受限通配
#3、“?Super T” 称为下限通配
——————————————————————————————————————————
为什么要使用通配符?
举个例子: 假设有方法public static double max(Stack<Number> s)
,如果调用 max(Stack<Integer> t)
则会报错,
Why? 因为:尽管Integer 是 Number 的子类,但是Stack<Integer>
不是Stack<Number>
的子类。所以定义方式时可用public static double max(Stack<?> s)
五、泛型的限制
#1、不能使用泛型类型参数来构建实例
比如错误: E object = new E();
#2、不能使用泛型类型参数构建数组
比如错误:E[] els = new E[10];
可以通过创建一个Object 数组,然后强转为E[],具体--> E[] els = (E[]) new Object[10];
#3、再静态环境下不允许类的参数是泛型的
比如错误:
public class Test<E>{
/*错误方法定义*/
public static void m(E o1){}
/*错误属性*/
public static E o1;
/*错误静态块*/
static{
E o2;
}
}
#4、异常类不能是泛型
比如错误: public class MyException<T> extends Expection{};
JVM 必须检查从这个try 子句中跑出的异常是否与catch子句中指定的类型匹配,这是不可能的,因为运行时类型信息是不出现的
try{
}catch(MyException<T> ex){
}