2. 2 M OTIVATIONS
Besoin de:
Déterminer une caractéristique d'un objet de façon
dynamique,
Pouvoir agir de façon générique sur un objet,
Pour cela, il est nécessaire de :
Disposer d'informations sur les méta données des
classes
Pouvoir agir sur un objet en ne connaissant pas le
champs ou la méthode concernés au moment de la
compilation
3. 3 LE BYTE CODE
Ne se limite pas à de simples instructions exécutables.
Contient de nombreuses informations plus proches du
code source du fichier .class : les méta données
Classe parente,
Interface implémentée,
Champs,
Méthodes
4. 4
C ONSÉQUENCES AU NIVEAU
DE L ' EXÉCUTION
Le premier domaine d'application est l'exécution,
Exemple:
Vous utilisez une bibliothèque pour écrire un
petit programme que vous compilez
Une nouvelle version de la bibliothèque devient
disponible. Vous remplacez le jar et relancez
votre programme
Java.lang.NoSuchMethodError At
MonProg.main(MonProg.java:36)
5. 5 L' UTILITAIRE JAVAP
Décompilateur élémentaire.
Classe parente,
Interface implémentée,
Champs,
Méthodes
Il est présent dans le répertoire jdkbin et sa
syntaxe de base est la suivante
javap monPaquetage.NomClasse
6. 6
C AS D ’ UTILISATIONS DE
L’API REFLECTION
Introspection = découverte des caractéristiques d'une
classe (classe mère, champs, méthodes, ...),
Instancier des classes de manière dynamique, en
agissant sur ses champs, en appelant ses méthodes ...
Écriture d'un générateur de code générique pour un
ensemble de classe.
Processus de sérialisation d'un bean Java ou dans la
génération du code de création d'un table en base de
données pour la persistance de la classe cible.
Pour tout outil devant faire abstraction des spécificités
d'une application en proposant un service générique
pour n'importe quelle classe.
7. PAQUETAGE JAVA . LANG . REFLECT: L A
7
CLASSE C LASS
Les instances sont des classes ou des interfaces,
Elle est indispensable pour pouvoir manipuler des méta
données
Exemple
public class Exemple {
public Exemple() { }
public String getNom(Object o) {
Class c = o.getClass();
return c.getName();
}
}
8. PAQUETAGE JAVA . LANG . REFLECT: L ES
8
MÉTHODES DE LA CLASSE C LASS
java.lang.reflect.Field getField(String name),
java.lang.reflect.Field[] getFields(),
java.lang.reflect.Method getMethod(String name, Class[]
parameterTypes),
java.lang.reflect.Method[] getMethods(),
java.lang.reflect.Constructor getConstructor(Class[] parameterTypes),
java.lang.reflect.Constructor[] getConstructors(),
Class[] getInterfaces(),
Class getSuperclass(),
java.lang.Package getPackage(),
9. PAQUETAGE JAVA . LANG . REFLECT: L A
9
CLASSE F IELD
Contient les informations sur un champ,
Quelques méthodes:
String getName()
Class getType()
int getModifier()
10. PAQUETAGE JAVA . LANG . REFLECT: L A
10
CLASSE M ODIFIER
Permet d’interpréter le modificateur renvoyé par
le field,
Quelques unes de ses méthodes
boolean static isFinal(int mod)
boolean static isPublic(int mod)
boolean static isStatic(int mod)
11. PAQUETAGE JAVA . LANG . REFLECT: L A
11
CLASSE M ETHOD
Contient les informations sur une méthodes,
Quelques méthodes:
Class[] getExceptionTypes()
String getName()
Class getReturnType()
Class[] getParameterTypes()
int getModifiers()
Dans le cas d’un type primitif, le wrapper est utilisé,
12. PAQUETAGE JAVA . LANG . REFLECT: L A
12
CLASSE C ONSTRUCTOR
Contient les informations sur un constructeur,
Quelques méthodes:
Class[] getExceptionTypes()
String getName()
Class[] getParameterTypes()
int getModifiers()
13. U TILISATION DE LA RÉFLEXIVITÉ : E DITION
13 ET CONSULTATION D ' UN CHAMP
void changeValeur(Object o, String
nomChamp, Object val) throws Exception {
Field f = o.getClass().getField(nomChamp);
f.set(o,val);
}
void afficheValeur(Object o, String nomChamp)
throws Exception {
Field f = o.getClass().getField(nomChamp);
System.out.println(f.get(o));
}
14. U TILISATION DE LA RÉFLEXIVITÉ :
14 INVOCATION D ’ UNE MÉTHODE
Object lancerMethode(Object o, Object[] args, String nomMethode) throws
Exception {
Class[] paramTypes = null;
if(args != null) {
paramTypes = new Class[args.length];
for(int i=0;i<args.length;++i) {
paramTypes[i] = args[i].getClass();
}
}
Method m = o.getClass() .getMethod(nomMethode,paramTypes);
return m.invoke(o,args);
}
15. 15
E XERCICE : I NSPECTEUR DE
CLASSE SIMPLE
Ecrire un inspecteur de classe simple capable de:
Lister toutes les signatures des méthodes de la
classe d’un objet,
Lister tous les champs de la classes d’un objet:
Déclaration du champ,
Valeur du champ,
16. 16
A U DELÀ DES RÈGLES DE
L ' ENCAPSULATION
Ce que permet de faire l'API Reflection dépasse
largement le cadre de l'encapsulation,
Jusqu'à présent nous avons consulté et agi sur
des champs et méthodes publiques,
Cette API permet d'inspecter tous les éléments
d'une classe, quelle que soit sa visibilité
17. A U DELÀ DES RÈGLES DE
17
L ' ENCAPSULATION : TRANSGRESSIONS
Transgression 1 : visibilité d’un membre invisible
getDeclaredFields et getDeclaredMethods pour
les membres publics, private et protected
Transgression 2: manipulation d’un membre
invisible
setAccessible(boolean b) permet de faire sauter le
verrou de sécurité
18. 18
A U DELÀ DES RÈGLES DE
L ' ENCAPSULATION : EXEMPLE
Soit une classe Secret avec un champ
privé priv (String).
void modifierChamp(Secret s, String val) {
Field f = s.getClass().getDeclaredField("priv");
f.setAccessible(true);
f.set(s,val);
}
19. AU DELÀ DES RÈGLES DE
19
L ' ENCAPSULATION : P ROTECTIONS
Il existe néanmoins des possibilités pour combler ce
manque de protection.
La méthode setAccessible est définie dans la
classe AccessibleObject (dont dérivent les
classes Field, Method et Constructor).
Définir qui possède le droit d'appeler la
méthode setAccessible en définissant
un SecurityManager.
Dépasse le cadre de la présentation,
Consulter le paquetage java.security,