2009-11-09 5 views
19

J'ai un morceau de code où j'ai besoin de passer la classe d'un champ dans une méthode. En raison de la mécanique de mon code, je ne peux manipuler que des objets de référence et non des primitives. Je veux un moyen facile de déterminer si un type Field est primitif et l'échanger avec la classe wrapper appropriée. Donc, dans le code ce que je fais jusqu'à présent est quelque chose comme ceci:Simple moyen d'obtenir le type de classe wrapper 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); 

Cela fonctionne bien, à l'exception du fait que je dois vérifier explicitement pour tous les types primitifs et les échanger avec la classe d'emballage approprié. Maintenant, je sais qu'il n'y a pas beaucoup de types primitifs et ce ne sera pas un problème de simplement les lister tous, mais je me demandais s'il y avait une façon plus facile et plus élégante de le faire.

Répondre

33

J'utilise Google Collections Bibliothèque dans ma réponse, parce que je suis gâté comme ça, mais vous pouvez probablement voir comment le faire avec des HashMaps simples si vous préférez.

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

Il est étrange que rien n'existe dans le JDK pour cela, mais en effet rien ne le fait.

EDIT: Je totalement oublié que nous avons publié ceci:

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

Il a la méthode wrap(), plus Déballer() et quelques autres accessoires.

+0

Donc, fondamentalement la même chose ... :) Merci pour la réponse. Fondamentalement, il n'y a pas d'autre moyen pour le moment. –

6

Vous pouvez appeler class.isPrimitive() pour savoir s'il s'agit d'une primitive ou non, mais il n'existe pas de méthode boxing pour convertir les classes dans le JDK. Il y a au moins un open bug relatif à ceci.

+0

Il y a aussi des champs dans les classes wrapper qui vous permettront d'accéder aux classes primitives (par exemple, 'Double.TYPE' est le même que 'double.class'), mais il n'y a pas de moyen non-laid de profiter de cela par programmation. –

5

Voici une autre façon, si vous n'avez pas besoin de code optimisé:

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

Il y a aussi com.sun.beans.finder.PrimitiveWrapperMap # getType (primitiveName). Mais bien sûr, l'utilisation de classes du paquet "com.sun" n'est pas vraiment recommandée ...

Questions connexes