6

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

  • 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

编辑: 我已经在下面的答案中发布了我选择的解决方案。无论如何,我勾选了汤姆的回答

4

3 回答 3

5

在我看来,您可以cc转换为它的子类CtPrimitiveType

如果您想要一个包装器,则可以使用方法getWrapperName来获取相应包装器的类名。您可以照常使用Class.forNameClass将该名称转换为对象。但是,我认为您不想要一个包装器,所以这无济于事。

相反,我认为你想要getDescriptor,然后是一个费力的手工编码 switch 语句:

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

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

于 2011-09-12T13:13:13.113 回答
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 语句。

谢谢你们的帮助。

于 2011-09-12T14:00:54.870 回答
1

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

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

于 2011-09-12T13:06:02.497 回答