0. 目录
- 1. 需求
- 2. 名词的解释
- 3. 获取T.class
- 3.1 前提条件
- 3.2 例子的类图
- 3.3 代码(具体的解释在代码中)
- 3.3.1 Parent类代码:
- 3.3.2 Son类代码
- 3.3.3 使用
- 输出的结果
1. 需求
在开发过程中,封装的过程中,避免不了要获得 泛型的class, 那么如何获取呢。
注意: 具体的解释在代码中
注意: 具体的解释在代码中
注意: 具体的解释在代码中
2. 名词的解释
在这之前呢,我们应该知道一些名词
- List<E> :E称为类型参数变量
- List<Integer> : Integer称为实际类型参数
- List<Integer> :List<Integer>称为参数化类型
3. 获取T.class
3.1 前提条件
再获取泛型的class之前呢,我想说的是:
获取T.class 的前提条件是
- 再父类中才能获取。
- 子类必须已经确定了父类的泛型,什么意思呢?比如这样
public class Son extends Parent<String> {…}
这样子就算是 子类再在继承的时候 已经确定了父类的泛型。- 使用的时候,实例化子类
3.2 例子的类图
3.3 代码(具体的解释在代码中)
3.3.1 Parent类代码:
public class Parent<T> {
private Class<T> clazz;
/**
* 无参构造方法
*/
public Parent() {
/**
* 获取直接父类
* 1. 注意,这个getClass() 方法获取的是谁的class呢?
* 如果是实例化的Parent的子类( new Son() ),那么实例化子类(Son)的时候,
* 必定会实例化Parent.所以此时getClass() 获取的是其子类(Son的)的class
* 那么 getGenericSuperclass(); 获取的是
* pers.lzy.test.Parent<java.lang.Integer>
* 因为我子类(Son)写的是 public class Son extends Parent<Integer> {}
* 所以他获取的是 pers.lzy.test.Parent<java.lang.Integer>
* 2. 如果你 实例化的是此类( new Parent<String>() )
* 那么getClass() 必定是 此类也就是Parent的class
* 之后再调用getGenericSuperclass(); 获取的是Object
* 那么抱歉,不用往下执行了,因为你已经不能获取T.class了,
* 因为Object上面并没有泛型,你不能往下解析了。
*
*/
Type type = this.getClass().getGenericSuperclass();
// 这里 强转成参数化类型:结果跟type一样:
// pers.lzy.test.Parent<java.lang.Integer>
// ParmeterizedType 为 type的子接口
ParameterizedType ptype = (ParameterizedType) type;
// 获取 实际类型参数(也就是<>里面的类型)
// 为什么是 数组呢???因为我们<>里面可以有多个, <String, Object>
// types值为:[class java.lang.Integer]
Type[] types = ptype.getActualTypeArguments();
// Class 为 Type 的实现类。
// 我们只要第一个元素,因为我们泛型定义了一个
// 强转成class。
// 现在我们就得到了泛型的class(T.class)
this.clazz = (Class<T>) types[0];
}
/**
* 使用clazz
* 打印class
*/
public void sayClass() {
System.out.println(clazz);
}
}
- 上面的代码 为啥能 反复强转?反复横跳(滑稽)。请看下面类图
3.3.2 Son类代码
/**
* @author immort(lzy)
* 注意,这里已经确定了 父类的泛型
*/
public class Son extends Parent<Integer> {
}
3.3.3 使用
/**
* 调用类
* @author immortal
*
*/
public class Client {
public static void main(String[] args) {
// 注意,这里一定是实例化的子类
// 不然肯定得不到T.class
Parent<Integer> son = new Son();
son.sayClass();
}
}
输出的结果