在我的程序中,我处理类和基本类型。如果程序找到一个类,它只需执行以下调用之一:
-
Class.forName(classname)
-
cc.toClass()
,其中cc
是CtClass
的实例
然而,如果它找到一个基本类型,事情就变得更糟了:
-
Class.forName
不可用,它不能与基本类型一起使用。 -
cc.toClass()
返回null
可以从基本类型包装器类调用TYPE
字段,但是我如何使用反射来实现呢?
CtClass cc;//Obtained from caller code
Class<?> classParam;
if (cc.isprimitive()) {
classParam= ?? // How can I get TYPE field value with reflection ?
} else {
String nomClasseParam = cc.getName();
if (nomClasseParam.startsWith("java")) {
classeParam = Class.forName(nomClasseParam);
} else {
classeParam = cc.toClass();
}
}
Javassist 3.12.0.GA
编辑:我把我选择的解决方案贴在了下面的答案里。不管怎样,我给汤姆的答案打了勾。
在我看来,你可以将cc
转换为它的子类CtPrimitiveType
如果您需要一个包装器,那么您可以使用getWrapperName方法来获取适当包装器的类名。你可以使用Class。forName将该名称转换为Class
对象。然而,我不认为你需要一个包装器,所以这没有帮助。
相反,我认为你想要getDescriptor,后面跟着一个费力的手工编码的开关语句:
switch(descriptor) {
case 'I': classParam = int.class; break;
// etc
}
像这样的东西真的应该在Javassist中。
根据Tom和momo的回应,我提出了以下解决方案:
CtClass cc; //Obtained from caller code
Class<?> classParam;
if (cc.isprimitive()) {
classParam = Class.forName(((CtPrimitiveType)cc).getWrapperName());
classParam = (Class<?>)classParam.getDeclaredField("TYPE").get( classParam );
} else {
String nomClasseParam = cc.getName();
if (nomClasseParam.startsWith("java")) {
classeParam = Class.forName(nomClasseParam);
} else {
classeParam = cc.toClass();
}
}
我调用CtPrimitiveType#getWrapperName
方法,然后我使用TYPE字段来获得基本类型类。我也避免写switch语句。
谢谢大家的帮助。
你可以做class。forName用于原语的对象包装(例如Integer用于原语int)。Java支持自动装箱,因此您可以在Object包装器和原始对等物之间进行交换。
我假设你正在使用JavaAssist的CtClass。如果cc
是一个原语,我认为它将是CtPrimitiveType
的类型(需要确认),在这种情况下,您可以强制转换并调用getWrapperName()来获得包装器类。