Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Java > 范型擦拭法即范型类无法获取范型参数信息的原因
【标  题】:范型擦拭法即范型类无法获取范型参数信息的原因
【关键字】:
【来  源】:http://www.blogjava.net/iamtin/archive/2006/05/08/45091.html

范型擦拭法即范型类无法获取范型参数信息的原因

Your Ad Here

江南白衣的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的方法。
我们应该利用这种特性,这对实现模版方法非常有用。
prototype.js dojo 中 javascript继承实现:【上一篇】
如何将.war包中的文件读取到服务器硬盘:【下一篇】
【相关文章】
没有相关文章
【随机文章】
  • 新概念jsp教程(全视频讲解)
  • 测试double和float类型由于精度限制造成的问题
  • 使用 Struts portlet 在门户应用程序中实现页面导航
  • CSS在IE和Nascape的显示差别
  • Visual C++ 编程技巧
  • 两大法宝助你挖掘游戏中的宝贝
  • Makefile解读
  • Linux 指令篇:讯息传送与信件管理--aliases
  • ATM网络层
  • XQuery引擎的两种应用
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.