Java学习笔记(六)
Contents
Java核心技术卷一基础知识第10版
#范型程序设计
- 构造函数中可以省略泛型类型。
1
ArrayList<String> file = new ArrayList<>()
- 出现编译错误比类在运行时出现类的强制类型转换异常要好得多。
类型参数
使得程序具有更好的可读性
和安全性
。- 泛型类可以有多个类型变量,例如
public class Pair<T, U> { ... }
。 - 泛型方法可以定义在普通类中,也可以定义在泛型类中。
- 类型变量放在修饰符的后面,返回类型的前面。
1
2
3
4
5class ArrayAlg {
public static <T> T getMiddle(T... a) {
return a[a.length / 2];
}
} - 当调用一个泛型方法时,在方法名前的尖括号中放人具体的类型:
1
String middle = ArrayAlg.<String>getMiddle("John", "Q.", "Public");
- 可以通过对类型变量 T 设置
限定
来对类型变量加以约束。1
public static <T extends Comparable> T min(T[] a) ...
- 一个类型变量或通配符可以有多个限定,例如:
T extends Comparable & Serializable
。限定类型用&
分隔,而,
用来分隔类型变量。 - 在 Java 的继承中,可以根据需要拥有多个接口超类型,但限定中至多有一个类。如果用 一个类作为限定,它必须是限定列表中的第一个。[1]
- 无论何时定义一个泛型类型,都自动提供了一个相应的原始类型(raw type)。
- 原始类型用第一个限定的类型变量来替换,如果没有给定限定就用
Object
替换。 - 当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。
1
2
3
4
5Pair<Employee> buddies = ...;
Employee buddy = buddies.getFirst();
// 1. 对原始方法 Pair.getFirst 的调用。
// 2. 将返回的 Object 类型强制转换为 Employee 类型。 - Java 泛型转换:
- 虚拟机中没有泛型,只有普通的类和方法。
- 所有的类型参数都用它们的限定类型替换。
- 桥方法被合成来保持多态。
- 为保持类型安全性,必要时插人强制类型转换。
- 桥方法:解决类型擦除与多态发生的冲突。[2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class DateInterval extends Pair<LocalDate> {
public void setSecond(LocalDate second) {
...
}
}
// 上述类擦除后会变成
class DateInterval extends Pair {
public void setSecond(LocalDate second) {
...
}
}
// 但会从Pair类中继承一个方法
class Pair {
public void setSecond(Object second) {
...
}
}
// 桥方法
public void setSecond(Object second) { setSecond((Date) second); } - 大多数 Java 泛型限制都是由类型擦除引起的。
- 不能用类型参数代替基本类型。
- 虚拟机中的对象总有一个特定的非泛型类型。
- 不能实例化参数化类型的数组。
- 不能实例化类型变置。
- 不能构造泛型数组。
- 带有超类型限定的通配符可以向泛型对象写人,带有子类型限定的通配符可以从泛型对象读取。