Introspection reflection
-
Upload
eric-toguem -
Category
Technology
-
view
385 -
download
0
Transcript of Introspection reflection
1
Eric TOGUEM, CIO AByster (www.abyster.com)
INTROSPECTION / REFLECTION EN JAVA
2 MOTIVATIONS
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 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
4CONSÉ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 L'UTILITAIRE JAVAP
Décompilateur élémentaire.
Classe parente,
Interface implémentée,
Champs,
Méthodes
Il est présent dans le répertoire jdk\bin et sa syntaxe de base est la suivante
javap monPaquetage.NomClasse
6CAS 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: LA
CLASSE CLASS
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: LES MÉTHODES DE LA CLASSE
CLASS
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: LA
CLASSE FIELD
Contient les informations sur un champ,
Quelques méthodes:
String getName()
Class getType()
int getModifier()
10
PAQUETAGE JAVA.LANG.REFLECT: LA
CLASSE MODIFIER
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: LA
CLASSE METHOD
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: LA
CLASSE CONSTRUCTOR
Contient les informations sur un constructeur,
Quelques méthodes:
Class[] getExceptionTypes()
String getName()
Class[] getParameterTypes()
int getModifiers()
13
UTILISATION DE LA RÉFLEXIVITÉ: EDITION 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
UTILISATION DE LA RÉFLEXIVITÉ: 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);
}
15EXERCICE: INSPECTEUR
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,
16AU 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
AU DELÀ DES RÈGLES DE 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é
18AU 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 L'ENCAPSULATION:
PROTECTIONS
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,