Rechercher dynamicment la classe qui représente un type Java primitif

Je dois faire des appels de méthode réflective en Java. Ces appels incluront des méthodes qui ont des arguments de type primitif (int, double, etc.). La manière de spécifier de tels types lors de la recherche de la méthode est int.class, double.class, etc.

Le défi est que j’accepte les entrées d’une source externe qui spécifieront les types dynamicment. Par conséquent, je dois également proposer ces références de classe de manière dynamic. Imaginez un fichier délimité une liste de noms de méthodes avec des listes de types de parameters:

doSomething int double doSomethingElse java.lang.Ssortingng boolean 

Si l’entrée était quelque chose comme java.lang.Ssortingng , je sais que je pourrais utiliser Class.forName("java.lang.Ssortingng") pour cette instance de classe. Est-il possible d’utiliser cette méthode, ou une autre, pour récupérer le type primitif Classes?

Edit: Merci à tous les répondants. Il semble clair qu’il n’existe aucun moyen intégré de faire proprement ce que je veux, alors je me contenterai de réutiliser la classe ClassUtils du framework Spring. Il semble contenir un remplacement pour Class.forName () qui fonctionnera avec mes exigences.

Le framework Spring contient une classe utilitaire ClassUtils qui contient la méthode statique pour Nom. Cette méthode peut être utilisée pour le but exact que vous avez décrit.

Au cas où vous n’aimeriez pas avoir une dépendance sur Spring: le code source de la méthode peut être trouvé e. g. ici sur leur repository public. Le code source de la classe est concédé sous le modèle Apache 2.0.

Notez cependant que l’algorithme utilise une carte codée en dur des types primitifs.


Edit: Merci aux commentateurs Dávid Horváth et Pasortingck pour avoir souligné le lien brisé.

Les instances de Class pour les types primitifs peuvent être obtenues comme vous l’avez dit en utilisant, par exemple, int.class , mais il est également possible d’obtenir les mêmes valeurs en utilisant quelque chose comme Integer.TYPE . Chaque classe d’enveloppe primitive contient un champ statique, TYPE , qui a l’instance de classe primitive correspondante.

Vous ne pouvez pas obtenir la classe primitive via forName , mais vous pouvez l’obtenir à partir d’une classe facilement disponible. Si vous devez absolument utiliser la reflection, vous pouvez essayer quelque chose comme ceci:

 Class clazz = Class.forName("java.lang.Integer"); Class intClass = clazz.getField("TYPE").get(null); intClass.equals(int.class); // => true 

Vous devez probablement mapper les primitives et pour le rest des classes, exécutez la méthode “forName”:

Je ferais quelque chose comme:

 void someWhere(){ Ssortingng methodDescription = "doSomething int double java.lang.Integer java.lang.Ssortingng" Ssortingng [] parts = methodDescription.split(); Ssortingng methodName= parts[0] Class [] paramsTypes = getParamTypes( parts ); // Well, not all the array, but a, sub array from 1 to arr.length.. Method m = someObject.class.getMethod( methodName, paramTypes ); etc. etc etc. } public Class[] paramTypes( Ssortingng [] array ){ List list = new ArrayList(); for( Ssortingng type : array ) { if( builtInMap.contains( type )) { list.add( builtInMap.get( type ) ); }else{ list.add( Class.forName( type ) ); } } return list.toArray(); } // That's right. Map builtInMap = new HashMap();{ builtInMap.put("int", Integer.TYPE ); builtInMap.put("long", Long.TYPE ); builtInMap.put("double", Double.TYPE ); builtInMap.put("float", Float.TYPE ); builtInMap.put("bool", Boolean.TYPE ); builtInMap.put("char", Character.TYPE ); builtInMap.put("byte", Byte.TYPE ); builtInMap.put("void", Void.TYPE ); builtInMap.put("short", Short.TYPE ); } 

C’est-à-dire créer une carte où les types de primitives sont stockés et si la description appartient à une primitive, utilisez alors la classe mappée. Cette carte peut également être chargée à partir d’un fichier de configuration externe, pour append de la souplesse, de sorte que vous ajoutez Ssortingng en tant que méthode intégrée à la place de java.lang.Ssortingng ou possédez une méthode comme celle-ci.

“doSomething ssortingng oui | non”

Il y a beaucoup de ce type de code dans les projets OS comme les librairies Struts, Hibernate, Spring et Apache (pour n’en citer que quelques-unes), vous n’avez donc pas besoin de partir de zéro.

BTW Je n’ai pas compilé le code ci-dessus, mais je suis sûr que cela fonctionne avec peu de modifications, mais ne me vote pas pour cela.

Apache Commons Lang a ClassUtils.getClass (Ssortingng) , qui prend en charge les types primitifs.

Un certain nombre de méthodes de classe ne gèrent malheureusement pas les primitives de manière cohérente. Une façon courante de contourner cela dans forName est d’avoir une table comme;

 private static final Map BUILT_IN_MAP = new ConcurrentHashMap(); static { for (Class c : new Class[]{void.class, boolean.class, byte.class, char.class, short.class, int.class, float.class, double.class, long.class}) BUILT_IN_MAP.put(c.getName(), c); } public static Class forName(Ssortingng name) throws ClassNotFoundException { Class c = BUILT_IN_MAP.get(name); if (c == null) // assumes you have only one class loader! BUILT_IN_MAP.put(name, c = Class.forName(name)); return c; } 

Le code suivant explique comment obtenir la classe d’un type primitif dont le nom de champ est connu, par exemple dans ce cas ‘sampleInt’.

 public class CheckPrimitve { public static void main(Ssortingng[] args) { Sample s = new Sample(); try { System.out.println(s.getClass().getField("sampleInt").getType() == int.class); // returns true System.out.println(s.getClass().getField("sampleInt").getType().isPrimitive()); // returns true } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } } class Sample { public int sampleInt; public Sample() { sampleInt = 10; } } 

On peut également vérifier si une valeur donnée est primitive ou non en obtenant sa classe de wrapper respective ou sa valeur de champ.

  public class CheckPrimitve { public static void main(Ssortingng[] args) { int i = 3; Object o = i; System.out.println(o.getClass().getSimpleName().equals("Integer")); // returns true Field[] fields = o.getClass().getFields(); for(Field field:fields) { System.out.println(field.getType()); // returns {int, int, class java.lang.Class, int} } } } 

Google Guava propose com.google.common.primitives.Primitives pour ce genre de choses.