2009-11-09 29 views
19

Tengo un fragmento de código donde necesito pasar la clase de un campo en un método. Debido a la mecánica de mi código, solo puedo manejar objetos de referencia y no primitivos. Quiero una manera fácil de determinar si el tipo Field es primitivo y cambiarlo por la clase contenedora apropiada. Así que en el código de lo que hago hasta ahora es algo como esto:Forma simple de obtener el tipo de clase contenedora en Java

Field f = getTheField(); // Dummy method that returns my Field 
Class<?> c = f.getType(); 
if (c == int.class) { 
    c = Integer.class; 
} 
else if (c == float.class) { 
    c = Float.class; 
} 
// etc 
myMethod(c); 

Esto funciona bien, excepto por el hecho de que tengo que comprobar de forma explícita para todos los tipos primitivos e intercambiarlos con la clase de contenedor apropiado. Ahora sé que no hay tantos tipos primitivos y que no será un problema simplemente enumerarlos a todos, pero me preguntaba si había una manera más fácil y más elegante de hacerlo.

Respuesta

33

Uso Google Collections Library en mi respuesta, porque estoy echado a perder de esa manera, pero probablemente pueda ver cómo hacerlo con HashMaps simples si lo prefiere.

// safe because both Long.class and long.class are of type Class<Long> 
    @SuppressWarnings("unchecked") 
    private static <T> Class<T> wrap(Class<T> c) { 
    return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c; 
    } 

    private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS 
    = new ImmutableMap.Builder<Class<?>, Class<?>>() 
     .put(boolean.class, Boolean.class) 
     .put(byte.class, Byte.class) 
     .put(char.class, Character.class) 
     .put(double.class, Double.class) 
     .put(float.class, Float.class) 
     .put(int.class, Integer.class) 
     .put(long.class, Long.class) 
     .put(short.class, Short.class) 
     .put(void.class, Void.class) 
     .build(); 

Es extraño que no existe nada en el JDK para esto, pero de hecho no lo hace.

EDIT: Me había olvidado por completo que hemos lanzado este:

http://google.github.io/guava/releases/21.0/api/docs/com/google/common/primitives/Primitives.html

Tiene el método de envoltura(), además de desenvolver() y algunas otras cosas incidentales.

+0

Así que básicamente lo mismo ... :) Gracias por la respuesta. Básicamente no hay otra manera en este momento. –

6

Puede llamar a class.isPrimitive() para saber si es una primitiva o no, sin embargo, no hay un método de boxeo para convertir las clases dentro del JDK. Hay al menos un open bug relacionado con esto.

+0

También hay campos en las clases contenedoras que le permitirán acceder a las clases primitivas (por ejemplo, 'Double.TYPE' es lo mismo que 'double.class'), pero no hay una forma no fea de aprovecharlo programáticamente. –

5

Aquí es otra manera si no se necesita el código altamente optimizado:

Class<?> primitive=long.class; 
    Class<?> boxed=Array.get(Array.newInstance(primitive,1),0).getClass(); 
    System.out.println(primitive.getName()); 
    System.out.println(boxed.getName()); 
0

También hay com.sun.beans.finder.PrimitiveWrapperMap # getType (primitiveName). Pero, por supuesto, no se recomienda el uso de las clases del paquete "com.sun" ...

Cuestiones relacionadas