提炼java reflectionWord文档格式.docx
- 文档编号:17096776
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:12
- 大小:18.67KB
提炼java reflectionWord文档格式.docx
《提炼java reflectionWord文档格式.docx》由会员分享,可在线阅读,更多相关《提炼java reflectionWord文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
|getClasses()|Array|Y|N
Field|getDeclaredField()|Single|N|Y
|getField()|Single|Y|N
|getDeclaredFields()|Array|N|Y
|getFields()|Array|Y|N
---------------------------------------------------------------------------------------------
Method|getDeclaredMethod()|Single|N|Y
|getMethod()|Single|Y|N
|getDeclaredMethods()|Array|N|Y
|getMethods()|Array|Y|N
Constructor|getDeclaredConstructor()|Single|N/A|Y
|getConstructor()|Single|N/A|N
|getDeclaredConstructors()|Array|N/A|Y
|getConstructors()|Array|N/A|N
表一:
成员方法对照表
如表一所示,getClasses()拥有继承的特点,可以获取父亲级定义的内部类,而不能访问定义为private的内部类;
而getDeclaredClasses()刚好相反,可以访问定义为private的内部类,却无法获取父亲级定义的内部类成
功获取了Class以后,那么就可以开始访问Field,Method和Constructor了,他们都继承自
java.lang.reflect.Member。
从上表已经很容易可以看出各个成员是否拥有继承特性,是否能够访问私有成员,返回类型的数量这些信
息。
这里需要注意一点,由于Constructor是无法被继承的,所以Constructor成员任何方法都没有继承的特性。
另外Field和
Method在赋值或者调用的之前需要留意是否在操作私有成员,如果是那么需要先修改可访问度,执行setAccessible(true)。
还有一点就
是Method成员的getDeclaredMethod()和getMethod()方法都需要两个参数,一个是方法的名称,另外一个参数Class的
数组,这里需要感谢Java5.0引入不定长参数的特点,使我们可以在某些情况下少传入一个参数,如:
假设Order类有下列方法
Java代码
publicLonggetId(){returnid;
}
}
5.0以前获取该方法的代码如下
MethodgetId=Order.class.getMethod("
getId"
newClass[0]);
而5.0仅需要写
);
现在说说5.0泛型出现之后,JavaReflection
API的新特点。
首先增加一个接口java.lang.reflect.Type,其下一共有4个接口继承了
它,TypeVariable,ParameterizedType,GenericArrayType和WildcardType,下面逐个分析。
1.TypeVariable
我们知道泛型信息会在编译时被JVM编译时转换为定义的一个特定的类型,这减少了应用程序逐步向下检查类型的开支,避免了发生
ClassCastException的危险。
而TypeVariable就是用来反映在JVM编译该泛型前的信息。
举个例子,假设BaseOrder类
定义有如下一个方法
publicclassBaseOrder&
lt;
MextendsObject&
amp;
Serializable,NextendsComparable&
N&
gt;
&
implementsIBaseOrder{
publicMgetManufactory(){
returnmanufactory;
}
implementsIBaseOrder{
publicMgetManufactory(){
returnmanufactory;
}
}这时候我们可以通过如下代码获取该泛型Type,并且经过测试该Type就是TypeVariable
FieldmanufactoryField=BaseOrder.class.getDeclaredField("
manufactory"
type=manufactoryField.getGenericType();
assertTrue("
ThetypeoffieldmanufactoryisaninstanceofTypeVariable"
typeinstanceofTypeVariable);
TypeVariabletType=(TypeVariable)type;
assertEquals("
ThenameofthisTypeVariableisM"
"
M"
tType.getName());
TheTypeVariableboundstwotype"
2,tType.getBounds().length);
OnetypeoftheseboundsisObject"
Object.class,tType.getBounds()[0]);
AndannothersiSerializable"
Serializable.class,tType.getBounds()[1]);
通过getName()方法可以获取该泛型定义的名称,而更为重要的是getBounds()方法,可以判断该泛型的边界。
2.ParameterizedType
这个接口就比较出名了,在过去讨论最多的问题就是GenericDao&
T&
中,如何获取T.class的问题了。
这里再翻出来过一遍,加入上述的类BaseOrder定义不变,新定义一个Order对象,代码如下:
publicclassOrder
extendsBaseOrder&
Customer,Long&
implementsIOrder,Serializable{
publicclassOrder
extendsBaseOrder&
implementsIOrder,Serializable{
}那么如何通过Order获取到Customer呢?
TypegenericSuperclass=Order.class.getGenericSuperclass();
Order‘ssupperclassisatypeofParameterizedType."
genericSuperclassinstanceofParameterizedType);
ParameterizedTypepType=(ParameterizedType)genericSuperclass;
Order‘ssupperclassisBaseOrder."
BaseOrder.class,pType.getRawType());
Type[]arguments=pType.getActualTypeArguments();
getActualTypeArguments()methodreturn2arguments."
2,arguments.length);
for(Typetype:
arguments){
Classclazz=(Class)type;
if(!
(clazz.equals(Customer.class))&
!
(clazz.equals(Long.class))){
assertTrue(false);
arguments){
Classclazz=(Class)type;
if(!
(clazz.equals(Long.class))){
assertTrue(false);
}可以看出通过Order类的getGenericSuperclass()方法将返回一个泛型,并且它就是
ParameterizedType。
这个接口的getRawType()方法和getActualTypeArguments()都非常重
要,getRawType()方法返回的是承载该泛型信息的对象,而getActualTypeArguments()将会返回一个实际泛型对象的数组。
这里先提及一下Class对象中getGenericSuperclass()和getSuperclass()两个方法的区别,后文还有详细说明。
getGenericSuperclass()方法首先会判断是否有泛型信息,有那么返回泛型的Type,没有则返回Class,方法的返回类型都是
Type,这是因为Tiger中Class也实现了Type接口。
将父亲按照Type接口的形式返回,而getSuperclass()直接返回父亲的
Class。
3.GenericArrayType
这个接口比较好理解。
如果泛型参数是一个泛型的数组,那么泛型Type就是GenericArrayType,它的getGenericComponentType()将返回被JVM编译后实际的数组对象。
这里假设上文中BaseOrder有一个方法如下:
publicString[]getPayments(String[]payments,List&
Product&
products){
returnpayments;
products){
returnpayments;
}可以看出该方法的参数中有泛型信息,测试一下:
MethodgetPayments=BaseOrder.class.getMethod("
getPayments"
newClass[]{String[].class,List.class});
types=getPayments.getGenericParameterTypes();
ThefirstparameterofthismethodisGenericArrayType."
types[0]instanceofGenericArrayType);
GenericArrayTypegType=(GenericArrayType)types[0];
TheGenericArrayType‘scomponentisString."
String.class,gType.getGenericComponentType());
发现这个getPayments()方法中的一个参数String[]
payments是一个GenericArrayType,通过getGenericComponentType()方法返回的是
String.class。
这是怎么回事呢?
这里我们回过头去看Class对象的getGenericSuperclass()方法和
getSuperclass()方法,如果把它们说成是一对的话,那么这里的getGenericParameterTypes()和
getParameterTypes()就是另外一对。
也就是说getGenericParameterTypes()首先判断该方法的参数中是否有泛型
信息,有那么返回泛型Type的数组,没有那么直接按照Class的数组返回;
而getParameterTypes()就直接按照Class的数组返
回。
非常相似吧,其原因就是这些成对的方法都有一个共同点就是判断是否有泛型信息,可以查看Tiger的源代码:
publicType[]getGenericParameterTypes(){
(getGenericSignature()!
=null)
returngetGenericInfo().getParameterTypes();
e
returngetParameterTypes();
publicType[]getGenericParameterTypes(){
if(getGenericSignature()!
=null)
returngetGenericInfo().getParameterTypes();
else
returngetParameterTypes();
}而这类成对出现的方法还很多,如Method对象定义的getGenericReturnType()和
getReturnType(),getGenericExceptionTypes()和getExceptionTypes(),Field对象定义
的getGenericType()和getType()。
4.WildcardType
这个接口就是获取通配符泛型的信息了。
这里假设上述的BaseOrder定义有一个属性
privateComparable&
?
extendsCustomer&
comparator;
现在就来获取泛型?
的信息,测试代码如下:
FieldcomparatorField=BaseOrder.class.getDeclaredField("
comparator"
ParameterizedTypepType=(ParameterizedType)comparatorField.getGenericType();
type=pType.getActualTypeArguments()[0];
ThetypeoffieldcomparatorisaninstanceofParameterizedType,andtheactualargumentisaninstanceofWildcardType."
typeinstanceofWildcardType);
WildcardTypewType=(WildcardType)type;
TheupperboundofthisWildcardTypeisCustomer."
Customer.class,wType.getUpperBounds()[0]);
type
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 提炼java reflection 提炼 java