:: Enseignements :: Master :: M1 :: 2014-2015 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Reflection et implantation de Map |
Exercice 1 - Introspector
Le but de cet exercice est d'implanter une méthode introspect
qui prend un objet quelconque et voit celui-ci comme une Map
qui associe à une chaine de caractère la valeur du getter correspondant.
Par exemple, si une classe Bar possède un méthode getFoo,
alors si on appel introspect avec une instance de la classe Bar
alors introspect va renvoyer un table de hachage qui pour la clé
"foo" possède la valeur de retour de la méthode getFoo.
En fait, pour vous aider, une partie du code de la classe
Introspectors
a déjà été écrit
.
-
Compléter le code de la méthode getValueByReflection pour que le code marche.
Comment doit-on gérer l'exception IllegalArgumentException, noter
que c'est une RuntimeException ?
Comment doit-on gérer l'exception IllegalAccessException ?
Que contient la cause de l'exception InvocationTargetException,
comment doit-on la gérer l'exception InvocationTargetException ?
-
Pourquoi l'appel Class.getMethods() fait nécessairement des copies défensives ?
Note: Regarder le type de retour de getMethods() et le fait que Method
possède une méthode setAccessible.
-
Comment améliorer le code en utilisant la classe ClassValue comme un cache ?
Modifier le code de la méthode introspect pour utiliser le cache.
-
Modifier le code qui créé le cache pour stocker des Map<String,Method>.
Si vous ne voyez pas pourquoi, vous pouvez lire la fin du sujet :)
Vous pouvez écrire la code de création du Map<String,Method>
en utilisant un Stream sur les méthodes et en appelant
Collectors.toMap(keyProjection, valueProjection).
-
On souhaite enfin que les modifications postérieures à la création de la Map
soit reflétées dans la Map.
java.awt.geom.Point2D point = new java.awt.geom.Point2D.Double(1, 2);
Map<String, Object> map2 = Introspectors.introspect(point);
System.out.println(map2); // { x = 1, y = 2, ... }
point.setLocation(7, 13);
System.out.println(map2); // { x = 7, y = 13, ... }
Ce veut donc dire que la Map renvoyée dois agir comme une vue de l'objet et
qu'il ne faut pas calculer les valeurs associées à chaque getter dans la méthode introspect.
Rappel: il existe une classe AbstractMap.
-
Enfin, faite en sorte que le test testSlooooow passe.
Exercice 2 - Introspectors 2 [A la maison]
L'introspector que nous avons écrit dans l'exercice 1 est uni-directionel,
les changements fait sur l'objet sont bien reportés sur la Map
mais le contraire n'est pas vrai. Un changement de valeur dans la Map,
avec un put par exemple, n'appel pas le setter de l'objet
(si celui-ci existe).
On se propose d'implanter ce changement.
-
Faire en sorte qu'un appel à put ou putAll sur la Map
renvoyé par la méthode introspect de la classe Introspectors2
appel le ou les setters correspondant sur l'objet.
© Université de Marne-la-Vallée