校园社交网站开发的目的与意义,php在线做网站,网站建设维护及使用管理办法,电商网站 建设价格转载自 Java通过Class的对象来获取泛型的class示例
在使用spring的JdbcTemplate实现DAO的时候#xff0c;经常会用到一个类ParameterizedBeanPropertyRowMapper。它的静态方法newInstance()接受一个Class类型的参数#xff0c;用于将ResultSet中的属性映射到传入的这个Class…转载自 Java通过Class的对象来获取泛型的class示例
在使用spring的JdbcTemplate实现DAO的时候经常会用到一个类ParameterizedBeanPropertyRowMapper。它的静态方法newInstance()接受一个Class类型的参数用于将ResultSet中的属性映射到传入的这个Class类型的Bean对象中再组成列表返回。 如果要想把这个DAO做成泛型的就必须要知道Class的类型。但是直接写成T.class显然是不行的。从网上查了不少资料结果只有一个由于Java的泛型实现使用了“擦拭法”具体细节没深究呵呵导致Java的泛型不能直接获取到自身的声明的泛型类型。 不过从江南白衣的blog文章里搜到了有用的东西使用反射来获得“T.class”。原文地址http://www.blogjava.net/calvin/archive/2009/12/10/43830.html 主要用到的是这么一句[c-sharp] view plain copyClass T entityClass (Class T) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 我查询了Java API在Class类中有这么两个方法 getGenericInterfaces()和getGenericSuperclass()先来看看这两个方法都是干什么用的1. public Type getGenericSuperclass()用来返回表示当前Class 所表示的实体类、接口、基本类型或 void的直接超类的Type。如果这个直接超类是参数化类型的则返回的Type对象必须明确反映在源代码中声明时使用的类型。比如
package com.mot.hyena.test;
import java.lang.reflect.ParameterizedType;
public class GT1 extends GT2Integer{ public static void main(String[] args) { System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass())); }
}
则输出结果即为com.mot.hyena.test.GT2java.lang.Integer如果此Class代表的是Object 类、接口、基本类型或 void则返回 null。。如果此对象表示一个数组类则返回表示 Object 类的 Class 对象。2. public Type[] getGenericInterfaces()与上面那个方法类似只不过Java的类可以实现多个接口所以返回的Type必须用数组来存储。以上两个方法返回的都是Type对象或数组在我们的这个话题中Class都是代表的参数化类型因此可以将Type对象Cast成ParameterizedType对象。而 ParameterizedType对象有一个方法 getActualTypeArguments()。public Type[] getActualTypeArguments()用来返回一个Type对象数组这个数组代表着这个Type声明中实际使用的类型。接着使用上面的例子
package com.mot.hyena.test;
import java.lang.reflect.ParameterizedType;
public class GT1 extends GT2Integer{ public static void main(String[] args) { System.out.println(((ParameterizedType)new GT1().getClass().getGenericSuperclass()).getActualTypeArguments()[0]); }
}
这次的显示结果将是class java.lang.Integer因此我们可以通过继承反射的方法来的到T.class。需要说明的是江南白衣使用的方法是将关键语句Class T entityClass (Class T ) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[ 0 ];放在了超类也就是声明泛型的那个类的构造方法中。这样一来子类在继承具有泛型的超类时会自动调用超类的构造方法。在此超类的构造方法中调用的getClass返回的是子类的Class类型与通常的重写机制有悖呵呵有待深究但测试结果确是如此则在子类中就无需再显式地使用 getGenericInterfaces()和getGenericSuperclass()等方法了。接着再使用(ClassT)对 getActualTypeArguments()返回的元素做casting即可得到所谓的T.class。
完整示例
Java通过Class的对象来获取泛型的class示例
[java] view plaincopy/** * 创建一个Class的对象来获取泛型的class */ private ClassT clz; SuppressWarnings(unchecked) public ClassT getClz(){ if (clznull) { clz(ClassT)(((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } return clz; } 此方法一般在模板方法中经常用到因此做一个笔记