江南白衣的Blog上一篇:
Java5泛型的用法,T.class的获取和为擦拭法站台
他参考的这里:
Generic Data Access Objects
我们的项目中也用的GenericHibernateDAO,里面使用了一个:
public
GenericHibernateDAO(
final
Class
<
E
>
clazz) {
this
.clazz
=
clazz;
}
的构造函数。
但是看了江南白衣的介绍,的确方便的可以写成:
public GenericHibernateDAO() {
this.clazz = (Class<E>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
这样,继承的子DAO就可以不用写Super(xxx.class)进行构造了。
其中的:
(Class
<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
非常神奇,看了faint的一个回复(请参照白衣的Blog):
package test;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import junit.framework.TestCase;
class TClass<T> {
}
class GoodClass<T> extends TClass<String> {
public ParameterizedType getClassT() {
return (ParameterizedType) getClass().getGenericSuperclass();
}
}
class BadClass<T> extends TClass<T> {
public ParameterizedType getClassT() {
return (ParameterizedType) getClass().getGenericSuperclass();
}
}
public class GenericsTest extends TestCase {
private void print(Type[] targs) {
System.out.print("actual type arguments are:");
for (int j = 0; j < targs.length; j++) {
System.out.print(" instance of " + targs[j].getClass().getName() + ":");
System.out.println(" (" + targs[j] + ")");
}
}
public void testGoodClass() throws Exception {
ParameterizedType type = new GoodClass<String>().getClassT();
Type[] types = type.getActualTypeArguments();
print(types);
assertEquals(TClass.class, type.getRawType());
assertEquals(String.class, types[0]);
}
public void testBadClass() throws Exception {
ParameterizedType type = new BadClass<String>().getClassT();
Type[] types = type.getActualTypeArguments();
print(types);
assertEquals(TClass.class, type.getRawType());
assertEquals(String.class, types[0]);
}
}
例子中的 BadClass 非常有意思,无法获取T的实际类型,我试验了半天也得不到。
看到也有朋友问这个问题:
http://forum.java.sun.com/thread.jspa?threadID=684429&messageID=3985573纳闷,怎么就不行呢。
翻了翻候捷的这篇文章:
http://www.jjhou.com/javatwo-2004-GP-in-jdk15.pdf才恍然大悟,原来对于BadClass这种情况就是获取不了它的Class。
这是擦拭法的本意。
实际上BadClass<String>()实例化以后Class里面就不包括T的信息了,对于Class而言T已经被擦拭为Object。而真正的T参数被转到使用T的方法(或者变量声明或者其它使用T的地方)里面(如果没有那就没有存根,这里指ParameterizedTyp),所以无法反射到T的具体类别,也就无法得到T.class。
而getGenericSuperclass()是Generic继承的特例,对于这种情况子类会保存父类的Generic参数类型,返回一个ParameterizedType,这时可以获取到父类的T.class了,这也正是子类确定应该继承什么T的方法。
我们应该利用这种特性,这对实现模版方法非常有用。
分享到:
相关推荐
消息传递范型与C/S范型双范型的主数据管理机制,陈晓云,邢乔金,本文针对主数据管理(MDM)存在的问题提出了一种基于消息传递机制范型与C/S范型双范型的主数据管理机制,当各个分系统的数据有所变化�
C++多范型设计,ISBN:9787508318240,作者:(美)James O.Coplien著;鄢爱兰,周辉等译;鄢爱兰译
分布式系统原理与范型第二版课后习题答案 分布式系统原理与范型第二版课后习题答案 分布式系统原理与范型第二版课后习题答案 分布式系统原理与范型第二版课后习题答案
《分布式系统原理与范型》第一版.中文版,影印版。
java1.5范型编程指南.docjava1.5范型编程指南.docjava1.5范型编程指南.docjava1.5范型编程指南.docjava1.5范型编程指南.doc
Java 范型Java 范型
书名:C++多范型设计 作者:[美]James O.Coplien 译者: 出版社:中国电力出版社 本书详细地介绍了从“应用领域”到“方案领域”的C++设计实现方法,以及开发者在设计思考和设计实践过程中需要用到的记法、图表和设计...
范型程序设计与 STL.pdf,大小约 300K。
《分布式系统原理与范型》是分布式系统中的经典教材,全书分为两部分:原理和范型。第一部分详细讨论了分布式系统的原理、概念和技术,其中包括通信、进程、命名、同步、一致性和复制、容错以及安全。第二部分给出了...
分布式系统原理与范型.pdf tanenbaum的早期操作系统著作
是《分布式系统原理与范型(第二版)》的答案 上回写错了,易造成误解! 本文档是第二版书的答案哦! 绝对是新的哦! 英文的!
第9章 范型和容器类.ppt第9章 范型和容器类.ppt
详细介绍分布式原理和基本范型, 是一部不可多得的分布式经典书籍。
第2~9章讨论的是分布式系统的的原理、概念和技术,包括通信、进程、命名、同步化、一致性和复制、容错性以及安全性等,而分布式应用的开发方法(即范型)在第10~13章中进行了讨论。但是,与前一版不同的是,我们...
C++多范型设计.pdfC++多范型设计.pdfC++多范型设计.pdf
分布式系统-原理与范型(第2版) 分布式系统-原理与范型(第2版) 分布式系统-原理与范型(第2版) 分布式系统-原理与范型(第2版)
华中科技大学 分布式系统原理与范型_考试_2009_答案
分布式系统原理与范型(下).pdf 清华大学出版社,不错的分布式教材。
分布式系统原理与范型中文版 经典分布式理论书籍