🐨泛型和反射
2021-3-10
| 2023-8-3
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
Java的部分反射API也是泛型。例如:Class<T>就是泛型:
调用ClassgetSuperclass()方法返回的Class类型是Class<? super T>
构造方法Constructor<T>也是泛型:
可以声明带泛型的数组,但不能用new操作符创建带泛型的数组:
必须通过强制转型实现带泛型的数组:
使用泛型数组要特别小心,因为数组实际上在运行期没有泛型,编译器可以强制检查变量ps,因为它的类型是泛型数组。但是,编译器不会检查变量arr,因为它不是泛型数组。因为这两个变量实际上指向同一个数组,所以,操作arr可能导致从ps获取元素时报错,例如,以下代码演示了不安全地使用带泛型的数组:
要安全地使用泛型数组,必须扔掉arr的引用:
上面的代码中,由于拿不到原始数组的引用,就只能对泛型数组ps进行操作,这种操作就是安全的。
带泛型的数组实际上是编译器的类型擦除:
所以不能直接创建泛型数组T[],因为擦拭后代码变为Object[]
必须借助Class<T>来创建泛型数组:
还可以利用可变参数创建泛型数组T[]
 
 

谨慎使用泛型可变参数

在上面的例子中,我们看到,通过:
似乎可以安全地创建一个泛型数组。但实际上,这种方法非常危险。
以下代码来自《Effective Java》的示例:
直接调用asArray(T...)似乎没问题,但是在另一个方法中,返回一个泛型数组就会产生ClassCastException,原因还是因为擦拭法,在pickTwo()方法内部,编译器无法检测K[]的正确类型,因此返回了Object[]
如果仔细观察,可以发现编译器对所有可变泛型参数都会发出警告,除非确认完全没有问题,才可以用@SafeVarargs消除警告。
如果在方法内部创建了泛型数组,最好不要将它返回给外部使用。
  • Java
  • super通配符集合
    目录