如何使用反射技术获取泛型类的真实类型?
2015-05-30 11:58
253 查看
平常我们需要获取某个类的类型,一般是直接使用 "实例.getClass()",获取 "类名 .class" 直接获取 。例如: 假设此时有一个User类,那么要获取该User类的真实类型的话,可以直接使用类名+".class"获取: ”User.class“
或者,通过User类的实例 user.getClass() 来获取;上面两个例子是已经确定该类的类型是User类型了,所以,才可以使用上面的方法。而泛型类因为还不能确定是什么类型,所以没办法使用上面的两个方法(实例.getClass(),类名.class);
如果类是泛型的话,那么该如何获取呢?我们可以通过获取该泛型类的子类的传入的类型参数来确定该泛型类的真实类型。如:有个类继承了一个泛型类,给该泛型类传入了一参数 "User" --->这个参数就是解决问题的关键点了
[/code]该泛型类BaseDaoImpl<T>的代码如下:
[/code]
BaseDaoImpl<T>的构造函数中的 this 指的是子类的实例。this.getClass()获取子类的真实类型;c.getGenericSuperclass(); 获取泛型父类t.getActualTypeArguments(); 通过该泛型父类来获取真实的类型参数的数组;也就是获取泛型父类的尖括号里面的参数<T>,因为泛型的尖括号是可以有多个参数的,所以该方法返回的是一个数组。p[0](既:t.getActualTypeArguments()[0]); 获取该数组的第一个值。因为我们知道在该例子中BaseDaoImpl<T>只有一个参数T。所以我们只需要获取第一个值就可以了。
在这里需要注意的是:范式应该在编译的时候就指定,而不是运行时。如果我把上面BaseDaoImpl(){ }改成如下这样子:[错误示范]
[/code]上面这段代码,因为在编译器进行编译的时候,还不能确定泛型的具体类型,所以会报如下的错误:java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType====================================================================结束。
来自为知笔记(Wiz)
或者,通过User类的实例 user.getClass() 来获取;上面两个例子是已经确定该类的类型是User类型了,所以,才可以使用上面的方法。而泛型类因为还不能确定是什么类型,所以没办法使用上面的两个方法(实例.getClass(),类名.class);
如果类是泛型的话,那么该如何获取呢?我们可以通过获取该泛型类的子类的传入的类型参数来确定该泛型类的真实类型。如:有个类继承了一个泛型类,给该泛型类传入了一参数 "User" --->这个参数就是解决问题的关键点了
public UserDao extends BaseDaoImpl<User>{
.....
}
[/code]该泛型类BaseDaoImpl<T>的代码如下:
public BaseDaoImpl() {
Class c = this.getClass();
Type t = c.getGenericSuperclass();
if (t instanceof ParameterizedType) {
// System.out.println("in if");
Type[] p = ((ParameterizedType) t).getActualTypeArguments();
// System.out.println(Arrays.toString(p));
this.clazz = (Class<T>) p[0];
}
}
[/code]
BaseDaoImpl<T>的构造函数中的 this 指的是子类的实例。this.getClass()获取子类的真实类型;c.getGenericSuperclass(); 获取泛型父类t.getActualTypeArguments(); 通过该泛型父类来获取真实的类型参数的数组;也就是获取泛型父类的尖括号里面的参数<T>,因为泛型的尖括号是可以有多个参数的,所以该方法返回的是一个数组。p[0](既:t.getActualTypeArguments()[0]); 获取该数组的第一个值。因为我们知道在该例子中BaseDaoImpl<T>只有一个参数T。所以我们只需要获取第一个值就可以了。
在这里需要注意的是:范式应该在编译的时候就指定,而不是运行时。如果我把上面BaseDaoImpl(){ }改成如下这样子:[错误示范]
public BaseDaoImpl() {
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
//输出结果,验证类型名称是否正确
//System.out.println("clazz --> " + clazz.getSimpleName()); //getSimpleName()是返回不包含包名的类名称
}
[/code]上面这段代码,因为在编译器进行编译的时候,还不能确定泛型的具体类型,所以会报如下的错误:java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType====================================================================结束。
来自为知笔记(Wiz)
相关文章推荐
- 多边形游戏(动态规划)
- 证明假如H是G的子群,那么与H共轭的子群个数等于[G:N(H)]
- selinux学习笔记
- C学习笔记(八)存储类、链接和内存管理
- The following classes could not be instantiated: android.support.v7.widget.ActionBarOverLayLayout
- Android 组件系列-----Activity的传值和回传值
- 排序算法总结之——归并排序
- 各尺寸图标
- 刀锋意志攻略
- 《JVM故障诊断指南》之6 —— JVM verbose GC 输出日志指南
- Unix多线程编程(一)
- 解决python version 2.7 required,which was not find in the registry
- C语言之头文件包含问题
- oc变量类型
- 再谈cocos2d-x屏幕适配
- 第五章 面向对象的编程风格(定义一个派生类)
- 数据结构之---C语言实现稀疏矩阵
- 复合对象的构造和析构顺序
- 验证:oracle delete 数据库空间是可以重新被使用的
- java基础--内部类