Как получить класс примитивных типов с Javassist? - PullRequest
6 голосов
/ 12 сентября 2011

В моей программе я имею дело с классами и примитивными типами. Если программа находит класс, она просто выполняет один из следующих вызовов:

  • 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

EDIT: Я разместил решение, которое я выбрал в ответах ниже. Во всяком случае, я поставил галочку Ответ Тома .

Ответы [ 3 ]

5 голосов
/ 12 сентября 2011

Мне кажется, что вы можете привести cc к его подклассу CtPrimitiveType .

Если вам нужна оболочка, вы можете использовать метод getWrapperName , чтобы получить имя класса соответствующей оболочки. Вы можете использовать Class.forName как обычно, чтобы превратить это имя в Class объект. Однако я не думаю, что вы хотите обертку, так что это не поможет.

Вместо этого, я думаю, вы хотите getDescriptor , за которым следует трудоемкий оператор переключения:

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

Что-то подобное действительно должно быть в Javassist. Но, насколько я понимаю, это не так.

3 голосов
/ 12 сентября 2011

Основываясь на ответах Тома и Момо, вот решение, которое я придумала:

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 для получения класса примитивного типа.Я также избегаю писать заявления о смене.

Спасибо за вашу помощь, ребята.

1 голос
/ 12 сентября 2011

Вы можете использовать Class.forName для обертки Object примитива (например, Integer для примитива int). Java поддерживает автобокс, так что вы можете обмениваться между оболочкой Object и примитивным аналогом.

Я предполагаю, что вы используете CtClass из JavaAssist. Если cc является примитивом, я думаю, что это будет тип CtPrimitiveType (необходимо подтвердить), в этом случае вы можете разыграть и вызвать getWrapperName () , чтобы получить класс-обертку.

...