Récupérer dynamiquement les classes des types génériques
KX
Messages postés
16761
Date d'inscription
Statut
Modérateur
Dernière intervention
-
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour,
Je voudrais encapsuler dans un objet Converter<X,Y> soit une méthode static qui prends un paramètre X et renvoie un objet Y, soit un constructeur de la classe Y qui prend en paramètre la classe X, afin ensuite de pouvoir convertir un objet X en Y, en s'assurant de la cohérence des types.
Actuellement mon code fonctionne, voici sa structure :
Le problème c'est que pour l'instant je suis obligé de passer en paramètres des objets de types Class<X> et Class<Y> pour faire mes tests, j'aimerais pouvoir les obtenir directement à partir de mes types génériques <X,Y> afin de simplifier ma structure et avoir seulement ceci :
Je ne sais pas si c'est possible, en tout cas je n'ai pas trouvé comment contourner le problème.
Je prends donc volontiers toute idée sur la question. Merci d'avance.
Voici le code complet pour voir pourquoi j'ai actuellement besoin de ces objets :
Je voudrais encapsuler dans un objet Converter<X,Y> soit une méthode static qui prends un paramètre X et renvoie un objet Y, soit un constructeur de la classe Y qui prend en paramètre la classe X, afin ensuite de pouvoir convertir un objet X en Y, en s'assurant de la cohérence des types.
Actuellement mon code fonctionne, voici sa structure :
private static class Converter<X,Y> { private final Method method; private final Constructor<Y> constructor; /** @param method : public static Y method(X) */ private Converter(Class<Y> y, Method method, Class<X> x); /** @param constructor : public Y(X) */ private Converter(Constructor<Y> constructor, Class<X> x); private Y parse(X x); }
Le problème c'est que pour l'instant je suis obligé de passer en paramètres des objets de types Class<X> et Class<Y> pour faire mes tests, j'aimerais pouvoir les obtenir directement à partir de mes types génériques <X,Y> afin de simplifier ma structure et avoir seulement ceci :
private static class Converter<X,Y> { private final Method method; private final Constructor<Y> constructor; /** @param method : public static Y method(X) */ private Converter(Method method); /** @param constructor : public Y(X) */ private Converter(Constructor<Y> constructor); private Y parse(X x); }
Je ne sais pas si c'est possible, en tout cas je n'ai pas trouvé comment contourner le problème.
Je prends donc volontiers toute idée sur la question. Merci d'avance.
Voici le code complet pour voir pourquoi j'ai actuellement besoin de ces objets :
private static class Converter<X,Y> { private final Method method; private final Constructor<Y> constructor; /** @param method : public static Y method(X) */ private Converter(Class<Y> y, Method method, Class<X> x) throws IllegalArgumentException { if (method==null) throw new IllegalArgumentException("method can't be null"); int modifiers = method.getModifiers(); if (!Modifier.isPublic(modifiers)) throw new IllegalArgumentException("method must be public: "+method.getName()); if (!Modifier.isStatic(modifiers)) throw new IllegalArgumentException("method must be static: "+method.getName()); if (method.getParameterTypes().length!=1) throw new IllegalArgumentException("method must take one and only one argument: "+method.getName()); if (!method.getParameterTypes()[0].isAssignableFrom(x)) throw new IllegalArgumentException("method must have a compatible argument: "+x+", "+method.getName()); if (!y.isAssignableFrom(method.getReturnType())) throw new IllegalArgumentException("method must have a compatible result: "+y+", "+method.getName()); this.method=method; this.constructor=null; } /** @param constructor : public Y(X) */ private Converter(Constructor<Y> constructor, Class<X> x) throws IllegalArgumentException { if (constructor==null) throw new IllegalArgumentException("constructor can't be null"); int modifiers = constructor.getModifiers(); if (!Modifier.isPublic(modifiers)) throw new IllegalArgumentException("constructor must be public: "+constructor.getName()); if (constructor.getParameterTypes().length!=1) throw new IllegalArgumentException("constructor must take one and only one argument: "+constructor.getName()); if (!constructor.getParameterTypes()[0].isAssignableFrom(x)) throw new IllegalArgumentException("constructor must have a compatible argument: "+x+", "+constructor.getName()); this.method=null; this.constructor=constructor; } @SuppressWarnings("unchecked") private Y parse(X x) throws RuntimeException { try { return method==null ? constructor.newInstance(x) : (Y) method.invoke(null, x); } catch (IllegalAccessException e) { throw new RuntimeException(method==null ? constructor.toGenericString() : method.toGenericString(),e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(x.toString(),e.getTargetException()); } catch (InstantiationException e) { throw new RuntimeException(constructor.toGenericString(),e); } } } public static void main(String[] args) throws Exception { Method parseInt = Integer.class.getMethod("parseInt", String.class); Converter<String, Integer> stringToInteger = new Converter<String, Integer>(int.class, parseInt, String.class); int n = stringToInteger.parse("123"); System.out.println(n); }
A voir également:
- Récupérer dynamiquement les classes des types génériques
- Comment récupérer les messages supprimés sur whatsapp - Guide
- Récupérer mon compte facebook désactivé - Guide
- Comment récupérer un compte facebook piraté - Guide
- Comment recuperer une video sur youtube - Guide
- Les types de ram - Guide
En effet pour vérifier que ma méthode est bien de la forme "public static Y method(X)", je dois vérifier que le paramètre est de type X (ou sous classe de X), de même que je dois vérifier que le type de retour est de type Y (ou super classe de Y). Or, les types X et Y je suis obligé de les passer en paramètres de la méthode alors qu'ils sont déjà spécifiés avec la généricité, je trouve ça idiot...
Quand dans mon main je fais "new Converter<String, Integer>(int.class, parseInt, String.class);" je précise deux fois les types de données, j'aimerais pouvoir alléger cette écriture en ne faisant que "new Converter<String, Integer>(parseInt);" en récupérant d'une manière ou d'une autre mes deux paramètres Class<X> x, et Class<Y> y, mais sans avoir à les mettre moi même dans la méthode...
J'aurais donc idéalement un code comme ça :
Mais si tu as d'autres idées je prends ;-)