如何使用Javassist获取原始类型的类?

时间:2011-09-12 12:25:14

标签: java reflection javassist

在我的程序中,我处理类和原始类型。 如果程序找到一个类,它只会执行以下调用之一:

  • Class.forName(classname)
  • cc.toClass()其中ccCtClass
  • 的实例

但是,如果它找到原始类型,事情会变得更糟:

  • 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

修改 我在下面的下面贴了the solution I chose。 无论如何,我勾选Tom's answer

3 个答案:

答案 0 :(得分:5)

在我看来,您可以将cc投射到其子类CtPrimitiveType

如果你想要一个包装器,那么你可以使用方法getWrapperName来获取相应包装器的类名。您可以像往常一样使用Class.forName将该名称转换为Class对象。但是,我认为你不想要一个包装器,所以这没有帮助。

相反,我认为你想要getDescriptor,然后是一个费力的手动编码开关声明:

switch(descriptor) {
    case 'I': classParam = int.class; break;
    // etc
}

类似的东西应该在Javassist中。但据我所知,事实并非如此。

答案 1 :(得分:3)

根据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语句。

感谢您的帮助。

答案 2 :(得分:1)

您可以为基元的Object包装器执行Class.forName(例如,原始int的Integer)。 Java支持自动装箱,因此您可以在Object包装器和原始对应项之间进行交换。

我假设您正在使用JavaAssist中的CtClass。 如果cc是原语,我认为它将是CtPrimitiveType的类型(需要确认),在这种情况下,您可以转换并调用getWrapperName()来获取包装类。