Bern University of Applied Sciences Engineering and Information Technology Reflection en Java José R. Beuret Juin 2008
est : un concept qui est présent dans Java, C#, Perl, etc... un moyen de récolter de l information à propos d un objet, en particulier sa structure interne. un moyen de créer un objet dynamiquement (sans appeler explicitement un constructeur).
Pour chaque instance de programme Java, la JVM génére deux espaces mémoires : Heap : Espace mémoire pour stocker les objets. Permanent : Espace mémoire pour stocker le code byte Java, c est à dire les classes. Ces deux espaces mémoires peuvent être représentés ainsi : Eden { }} { Tenured { }} { } {{ } Heap } {{ } Permanent
Visualisation 1/2 Visualisation 2/2 Nous souhaitons créer un objet de type T. Si aucun objet de ce type n a été créé, alors les étapes suivantes se réalisent : La JVM charge le code byte de la class T dans l espace Permanent Un unique objet de type Class représentant la classe T est crée. Cet objet est placé dans le Permanent La référence de l objet de type Class est mise dans le code byte de la classe. L objet de type T est enfin créé, cet objet possède une référence sur l unique objet représentant de la classe T.
Visualisation 1/2 Visualisation 2/2 S il existe l unique objet de type Class représentant le type T, en d autres termes un objet de type T a déjà été créé, alors les étapes suivantes se réalisent : L objet de type T est créé. Cet objet possède une référence sur l unique objet représentant sa classe T.
Visualisation 1/2 Visualisation 1/2 Visualisation 2/2 String Joe = new String() ; Heap { }} { Permanent { }} {
Visualisation 1/2 Visualisation 1/2 Visualisation 2/2 String Joe = new String() ; Classe String {}}{
Visualisation 1/2 Visualisation 1/2 Visualisation 2/2 String Joe = new String() ; Instance de type Class {}}{
Visualisation 1/2 Visualisation 1/2 Visualisation 2/2 String Joe = new String() ; Objet Joe {}}{
Visualisation 2/2 Visualisation 1/2 Visualisation 2/2 String Jane = new String() ; Objet Joe {}}{
Visualisation 2/2 Visualisation 1/2 Visualisation 2/2 String Jane = new String() ; Objet Jane {}}{
Utiliser le Utiliser le Utiliser le L abréviation signifie Runtime Type Identification. Le est un outils pour permettre l identification d un type dynamiquement. Le en Java est effectué en utilisant l unique objet représenant de la classe.
Utiliser le Utiliser le Utiliser le Utiliser le Il est possible d accéder à l unique représentant d une classe par l attribut static class de cette classe. Class c1 = String.class ; Class c2 = String[].class ; Class c3 = Object.class ; Class c4 = Class.class ; Class c5 = JFrame.class ;
Utiliser le Utiliser le Utiliser le Utiliser le Il est aussi possible d accéder à l unique représentant d une classe via une instance de ce type en appelant la méthode getclass(). Class c1 = new String().getClass() ; Class c2 = new String[6].getClass() ; Class c3 = new Object().getClass() ; Class c4 = new Object().getClass().getClass() ; Class c5 = new JFrame().getClass() ;
Utiliser le Utiliser le Utiliser le Utiliser le Il est aussi possible d accéder à l unique représentant d une classe via une méthode static appelé forname(string) de la classe Class. Class c1 = Class.forName( java.lang.string ) ; Class c2 = Class.forName( [Ljava.lang.String ; ) ; Class c3 = Class.forName( java.lang.object ) ; Class c4 = Class.forName( java.lang.class ) ; Class c5 = Class.forName( javax.swing.jframe ) ;
Reflection Informations Informations Informations Sécurité Sécurité est appurue avec Java 1.1. Sun Microsystems a choisi d utiliser son comme point d ancrage.
Informations contenues Informations Informations Informations Sécurité Sécurité Les informations obtenues par la sont les suivantes : Les attributs Les constructeurs Les méthodes La superclasse Les interfaces implémentées Il est donc possible d obtenir toutes les informations par récurrence.
Informations contenues Informations Informations Informations Sécurité Sécurité Il est possible de récupérer un array de tout les attributs public de la classe ainsi que ceux hérités. Field[] getfields() Il est également permis de récupérer l attribut dont le nom est spécifié en paramètre. L attribut ne doit pas forcément être public. Field getfield(string nom) Il y a une méthode pour récupérer uniquement les attributs présent dans la classe elle-même. Avec cette méthode, les attributs renvoyés ne sont pas forcément public. Field[] getdeclaredfields()
Informations contenues Informations Informations Informations Sécurité Sécurité La méthode pour récupérer la superclasse est : Class getsuperclass() La méthode pour récupérer les interfaces est : Class[] getinterfaces()
Informations Informations Informations Sécurité Sécurité Une fois obtenu un objet de type Field, il est possible d accéder au contenu de cet attribut par la méthode get(object) de modifier le contenu de cet attribut par la méthode set(object, Object)
Informations Informations Informations Sécurité Sécurité c l a s s Personne { p u b l i c S t r i n g nom ; } p u b l i c Personne ( S t r i n g nom) { t h i s. nom = nom ; } p u b l i c c l a s s R e f l e c t i o n { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { Personne p = new Personne ( Jean ) ; C l a s s p C l a s s = p. g e t C l a s s ( ) ; F i e l d p F i e l d = p C l a s s. g e t F i e l d ( nom ) ; O b j e c t hack = p F i e l d. g e t ( p ) ; p F i e l d. s e t ( p, Hacker + ( S t r i n g ) hack ) ; } } System. out. p r i n t l n ( p. nom ) ;
Informations Informations Informations Sécurité Sécurité Une fois obtenu un objet de type Method, il est possible d invoquer la méthode par invoke(object, Object[]). Si la méthode est static le premier argument peut être null.
Informations Informations Informations Sécurité Sécurité Une fois obtenu un objet de type Constructor, il est possible de créer une instance sans connaitre son type par la méthode newinstance(object[]). Afin de pouvoir déterminer le type d une instance dynamiquement, une instance de type Class dispose d une méthode isinstance(object).
Sécurité Informations Informations Informations Sécurité Sécurité ne tient pas compte des modificateurs d accessibilité (private, protected, public ou package). Il est donc possible d accéder à des éléments privés (constructeur, méthode ou attribut) Java propose des gestionnaires de sécurité qui fournissent des droits.
Informations Informations Informations Sécurité Sécurité c l a s s Personne { p r i v a t e S t r i n g nom ; // } p u b l i c Personne ( S t r i n g nom) { t h i s. nom = nom ; } p u b l i c c l a s s R e f l e c t i o n { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { Personne p = new Personne ( Jean ) ; C l a s s p C l a s s = p. g e t C l a s s ( ) ; F i e l d p F i e l d = p C l a s s. g e t F i e l d ( nom ) ; p F i e l d. s e t A c c e s s i b l e ( t r u e ) ; // O b j e c t hack = p F i e l d. g e t ( p ) ; p F i e l d. s e t ( p, Hacker + ( S t r i n g ) hack ) ; } } System. out. p r i n t l n ( p. nom ) ;
Sécurité Informations Informations Informations Sécurité Sécurité Nous connaissons déjà des gestionnaires de sécurité : Les applications ne peuvent pas accéder au disque dur, si elles sont lancées depuis un IDE. Les applets ne peuvent pas accéder au disque dur. Les gestionnaires possèdent des permissions, l une d entre elles étant d autoriser la.
Application théorique Notion de sous type ( sous classe) Functor (vs Interface) Application pratique Server de tâches, Cluster Application IDE Gestion dynamique
Voici les références les plus importantes : http://en.wikipedia.org/wiki/reflection_ %28computer_science%29 http://pagesperso-orange.fr/emmanuel.remy/java/ Tutoriels/TechniquesSup/reflexion.html Notes de conférence, JUGL, Karim Mazouni, Profiler dans NetBeans