1,泛型类的定义:
class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}
2,泛型类的使用:
泛型类<类型实参> 变量名; // 定义一个泛型类引用。
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象。
3,裸类型:
裸类型是一个泛型类但没有带着类型实参,例如 MyArrayList 就是一个裸类型。
MyArrayList list = new MyArrayList();
4,泛型类的定义-类型边界
在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。
class 泛型类名称<类型形参 extends 类型边界> {
...
}
eg:
public class MyArrayList<E extends Number> {
...
}
5,类型擦除:
泛型是作用在编译期间的一种机制,实际上运行期间是没有这么多类的,即类型擦除主要看其类型边界而定。
编译器在类型擦除阶段:
1. 将类型变量用擦除后的类型替换,即 Object 或者 Comparable
2. 加入必要的类型转换语句
3. 加入必要的 bridge method 保证多态的正确性
6. 泛型类的使用-通配符:
?用于在泛型的使用,即为通配符。
// 可以传入任意类型的 MyArrayList
public static void printAll(MyArrayList<?> list) {
...
}
1,通配符-上界:<? extends 上界>
2,通配符-下界:<? super 下界>
注意:
1,泛型类无法直接创建数组。要创建一个泛型类的数据必须定义为Object类,通过强制转换为泛型类。 E[] arrray=(E[])new Object[16]。
2,当自定义实现TreeMap底层代码时,定义泛型时必须是Comparable的,并且可以是可以和另一个泛型类做比较的。
3,泛型类型参数不支持基本数据类型
4, 无法实例化泛型类型的对象
5, 无法使用泛型类型声明静态的属性
6, 无法使用 instanceof 判断带类型参数的泛型类型
7,无法 create、catch、throw 一个泛型类异常(异常不支持泛型)
8,泛型类型不是形参一部分,无法重载