I NTROSPECTION / R EFLECTION
EN J AVA
             www.abyster.com

                1
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                             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
        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                 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
                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.
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();
               }
         }
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(),
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()
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)
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é,
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()
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));
     }
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
          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
            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é
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
              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);
         }
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,

Introspection reflection

  • 1.
    I NTROSPECTION /R EFLECTION EN J AVA www.abyster.com 1
  • 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,