泛型约束与局限性(上)
-
由于类型擦除,所以不能使用基本类型实例化类型参数,
Object
不能存储基本类型的值(基本类型的包装类可以)。 -
不能使用
instanceof
比较两个泛型变量的类型参数是否相等,只能比较它们是否为同一泛型。ArrayList<Number> arrayList = new ArrayList<>(); // 报错泛型类型不合法 System.out.println(arrayList instanceof ArrayList<Number>); // 这样是合理的 System.out.println(arrayList instanceof ArrayList); // true
-
不能创建参数化类型的数组。
ArrayList<Number>[] arrays = new ArrayList<Number>[10]; // 在类型擦除后 ArrayList<Number>[] arrays // 相当于 ArrayList[] arrays // 此时如果这样做也是可以的 ArrayList[] arrays = new ArrayList<String>[10]; // 可以通过数组存储检查,但是会导致类型错误。所以不允许这样创建。
-
可变参数数组警告。
我们知道可变参数类型例如
public Integer max(Integer ...args) { // ... }
此时
Integer ...args
本质是一个数组。所以如果是下面这样
public <T> T max(T ...args, Comparator<T> comparator) { // ... }
T ...args
不就相当于创建了一个参数化类型的数组吗?这违反了第三条。但是在这种情况下规则会放松,你会得到一个警告而不是错误。可以使用@SafeVarargs
来压制错误。但其实风险并没有解除。