Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get class of primitive types with Javassist?

In my program, I deal with classes and primitive types. If the program finds a class, it simply does one of the following calls :

  • Class.forName(classname)
  • cc.toClass() where cc is an instance of CtClass

However, if it finds a primitive type, things get worse :

  • Class.forName is not usable, it cannot be used with primitive types.
  • cc.toClass() returns null

It's possible to call the TYPE field from primitive types wrapper class but how can I do it with reflection ?

Here is my code :

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: I have posted the solution I chose in the anwsers below. Anyway, I ticked Tom's answer.

like image 907
Stephan Avatar asked Sep 12 '11 12:09

Stephan


2 Answers

It looks to me like you can cast cc to its subclass CtPrimitiveType.

If you wanted a wrapper, you could then use the method getWrapperName to get the class name of the appropriate wrapper. You can use Class.forName as usual to turn that name into a Class object. However, i don't think you do want a wrapper, so this doesn't help.

Instead, i think you want getDescriptor, followed by a laboriously handcoded switch statement:

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

Something like that really should be in Javassist. But as far as i can see, it isn't.

like image 120
Tom Anderson Avatar answered Sep 28 '22 06:09

Tom Anderson


Based on responses from Tom and momo, here is the solution I came up with :

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();
    }
 }

I call CtPrimitiveType#getWrapperName method and then I use the TYPE field to get the primitive type class. I also avoid writing a switch statement.

Thanks for your help guys.

like image 42
Stephan Avatar answered Sep 28 '22 06:09

Stephan