2011-09-12 15 views
6

En mi programa, trato con clases y tipos primitivos. Si el programa encuentra una clase, sino que simplemente hace una de las siguientes llamadas:¿Cómo obtener la clase de tipos primitivos con Javassist?

  • Class.forName(classname)
  • cc.toClass() donde cc es una instancia de CtClass

Sin embargo, si encuentra un tipo primitivo, las cosas empeoran:

  • Class.forName no se puede utilizar, no se puede utilizar con tipos primitivos.
  • cc.toClass() vuelve null

Es posible llamar el campo TYPE de tipos primitivos contenedor de clase, pero ¿cómo puedo hacerlo con la reflexión?

Aquí está mi código:

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: He publicado the solution I chose en los anwsers abajo. De todos modos, marqué Tom's answer.

+2

Esta otra pregunta definitivamente ayudará: [boolean.class?] (Http://stackoverflow.com/questions/1019208/boolean-class) –

+0

@Andreas_D No mucho, ya que quiero realizar la llamada con reflejo de java. – Stephan

+0

pero * podemos * usar 'boolean.class',' int.class' y así sucesivamente como objetos 'Clase' cuando reflejamos métodos y constructores –

Respuesta

5

Me parece que puede convertir cc en su subclase CtPrimitiveType.

Si desea un contenedor, puede utilizar el método getWrapperName para obtener el nombre de clase del contenedor adecuado. Puede usar Class.forName como de costumbre para convertir ese nombre en un objeto Class. Sin embargo, no creo que quieras una envoltura, así que esto no ayuda.

En cambio, creo que quieres getDescriptor, seguida de una sentencia switch laboriosamente handcoded:

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

Algo así como que realmente debería estar en Javassist. Pero por lo que puedo ver, no lo es.

+0

' getDescriptor' por qué no, instrucción de cambio laborioso para escribir ... – Stephan

+0

Finalmente, uso 'getWrapperName' y evito tener que codificar una instrucción switch – Stephan

+0

Dado que solo hay ocho tipos primitivos , no sería * tan * laborioso de escribir. –

1

Puede hacer el Class.forName para el envoltorio Object de la primitiva (por ejemplo, Integer para primitive int). Java admite el autoboxing, por lo que puede intercambiar entre el contenedor de objetos y la contraparte primitiva.

Supongo que está utilizando CtClass de JavaAssist. Si cc es una primitiva, creo que será un tipo de CtPrimitiveType (necesidad de confirmar) en cuyo caso podría lanzar y llamar al getWrapperName() para obtener la clase contenedora.

+1

No es cierto en el mundo de la reflexión. :( – dacwe

+0

Tiene razón, Java admite el autoboxing pero la clase que manipulo es generada dinámicamente por Javassist. La clase generada tiene un método con el parámetro 'int. El cargador de clases no puede encontrar este método si le doy' java. lang.Integer' parameter en 'Class.forName' – Stephan

+0

@dawce Argh, no sabía que :(debería jugar más con la reflexión. Stephan parece que la respuesta de Tom debería funcionar. – momo

3

Con base en las respuestas de Tom y momo, aquí está la solución que se me ocurrió:

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

me llaman CtPrimitiveType#getWrapperName método y luego utilizar el campo TYPE para obtener la clase de tipo primitivo.También evito escribir una declaración de cambio.

Gracias por su ayuda chicos.

Cuestiones relacionadas