本篇博客将详细讲解Java中的泛型。
class 泛型类名称<类型形参列表> {
//这里可以使用类型参数
}
class 泛型类名称<类型形参列表> extends 继承类 {
//这里可以使用类型参数
}
类型形参一般使用一个大写字面表示,常用名称有:
class MyArray<T> {
public T[] objects = (T[]) new Object[10];
public void set(int pos, T val) {
objects[pos] = val;
}
public T get(int pos) {
return objects[pos];
}
}
泛型类<类型实参> 变量名; //定义一个泛型类引用
new 泛型类<类型实参> (构造方法实参); //实例化一个泛型类对象
当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写
MyArray<String> list = new MyArray<>();
在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。
class 泛型类名称<类型形参 extends 类型边界> {
...
}
public class MyArray<E extends Number> {
...
}
泛型是作用在编译期间的一种机制,实际上运行期间是没有这么多类的,因此存在类型擦除。例如:
class MyArray<T> {
// T会被擦除为Object
}
class MyArray<E extends Comparable<E>> {
// E会被擦除为Comparable
}
类型擦除主要看其类型边界而定。
编译器在类型擦除阶段在做什么?
将类型变量用擦除后的类型替换,即 Object 或者 Comparable
加入必要的类型转换语句
加入必要的
bridge method
保证多态的正确性
?
用于泛型的使用,即为通配符。
public class MyArray<T> {
...
}
public static void printAll(MyArray<?> list) {
//可以传入任意类型的MyArray
}
<? extends 上界>
public static void printAll(MyArray<? extends Number> list) {
//可以传入类型实参是Number子类的任意类型的MyArray
}
<? super 下界>
public static void printAll(MyArray<? super Integer> list) {
//可以传入类型实参是Integer父类的任意类型的MyArray
}
注意:
MyArrayList<Object>
不是MyArrayList<Number>
的父类型
MyArrayList<Number>
也不是MyArrayList<Integer>
的父类型
需要使用通配符来确定父子类型
MyArrayList<?>
是MyArrayList<? extends Number>
的父类型 MyArrayList<? extends Number>
是MyArrayList<Integer>
的父类型
裸类型是一个泛型类但没有带着类型实参,例如:
MyArray list = new MyArray();
方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) {
...
}
class A<T extends Comparable<T>> {
public T findMax(T[] array) {
T max = array[0];
for (int i = 0; i < array.length; i++) {
if (max.compareTo(array[i]) < 0) {
max = array[i];
}
}
return max;
}
//如果是静态方法
public static<T extends Comparable<T>> T findMax(T[] array) {
T max = array[0];
for (int i = 0; i < array.length; i++) {
if (max.compareTo(array[i]) < 0) {
max = array[i];
}
}
return max;
}
}
泛型类型参数不支持基本数据类型
无法实例化泛型类型的对象
无法使用泛型类型声明静态的属性
无法使用 instanceof 判断带类型参数的泛型类型
无法创建泛型类数组
无法 create、catch、throw 一个泛型类异常(异常不支持泛型)
泛型类型不是形参一部分,无法重载
本篇博客到此结束。
上一篇博客:Java学习苦旅(二十)——七大排序(JAVA代码)
下一篇博客:Java学习苦旅(二十二)——Map&Set