Accueil
Accueil
Le
Club
Delphi
Kylix
C
C++
Java
J2EE
DotNET
& C#
Visual
Basic
Access
Pascal
Dev
Web
PHP
ASP
XML
UML
SQL
SGBD
Win
Linux
Autres



A quoi sert l'introspection ou la réflexivité, et comment l'utiliser ?
auteur : Ricky81
L'introspection consiste en la découverte dynamique des informations propres à une classe Java ou à un objet. Ce mécanisme est notamment utilisé au niveau de la machine virtuelle Java lors de l'exécution de votre programme, et donne lieu à une API.

Le paquetage java.lang.reflect permet l'introspection en rendant possible l'accès aux classes, à leurs champs, méthodes ou encore constructeurs, et à toutes les informations les caractérisant, même celles qu'on pensaient inaccessibles Elle est également très utile pour instancier des classes de manière dynamique, dans le processus de sérialisation d'un bean Java, ainsi que dans la génération de code.

Les méta données présentes dans les fichiers binaires renseignent sur le contenu de chaque classe répertoriée et permettent à la jvm de procéder à des vérifications lors de l'exécution d'un programme (pensez à l'exception java.lang.NoSuchMethodError).
La jvm utilise également ces informations pour vous proposer la complétion de code dans les environnements de développement Java, ce qui se fait en temps réel (pas de génération à faire au préalable).

Des détails sur le format des méta données dans un fichier binaire sont disponibles dans les documents de spécification de la machine virtuelle Java. Sachez seulement que les champs et méthodes sont identifiés par leur nom, le type (identifiants spécifiques à la jvm) pour les champs, et la signature pour les méthodes. A partir de ces informations, la jvm sait directement localiser la portion de byte code correspondant à l'implémentation d'une méthode.

lien : API Reflection

Comment connaître l'ensemble des classes dont hérite une classe ?
auteur : Ricky81
Il existe dans la classe Class une méthode nommée getSuperClass(), c'est cette méthode que nous allons utiliser.

Class c = Class.forName("maClasse"); while((c=c.getSuperclass()) != null) { System.out.println(c.getName()); }
lien : API Reflection

Comment connaître l'ensemble des interfaces qu'implémente une classe ?
auteur : Ricky81
Il existe dans la classe Class une méthode nommée getInterfaces() qui renvoie un tableau des interfaces implémentées par la classe.

Class c = Class.forName("maClasse"); Class[] interfaces = c.getInterfaces(); for(int i=0;i<interfaces.length:++i) { System.out.println(interfaces[i].getName()); }
lien : API Reflection

Comment connaître le nom du paquetage dans lequel se situe une classe ?
auteur : Ricky81
Il existe dans la classe Class une méthode nommée getPackage() qui renvoie un objet de type java.lang.Package.

Class c = Class.forName("monPackage.maClasse"); Package p = c.getPackage(); System.out.println(p.getName());
lien : API Reflection

Comment récupérer la liste des méthodes d'une classe ?
auteur : Ricky81
La liste des méthodes publiques (même celles héritées) est disponible grâce à la méthode getMethods().

Class c = Class.forName("maClasse"); java.lang.reflect.Method[] m = c.getMethods();
Il est également possible de récupérer une méthode par son nom et sa signature en utilisant la méthode :

getMethod(String name, Class[] parameterTypes)
lien : Est-il possible d'avoir la liste des champs/méthodes privés et protégés d'une classe ?
lien : Comment récupérer la liste des champs d'une classe ?
lien : API Reflection

Comment connaître la signature d'une méthode ?
auteur : Ricky81
La classe java.lang.reflect.Method dispose d'un certain nombre de méthodes permettant de reconstituer la signature d'une méthode. Voici un exemple de deux d'entre elles :

// m est un objet de type Method Class r = m.getReturnType(); Class[] params = m.getParameterTypes();
lien : API Reflection

Comment récupérer la liste des champs d'une classe ?
auteur : Ricky81
Il existe dans la classe Class une méthode nommée getFields(), c'est cette méthode que nous allons utiliser.

Class c = Class.forName("maClasse"); java.lang.reflect.Field[] f = c.getFields();
Il est également possible de récupérer un champ par son nom en utilisant la méthode getField(String name).

lien : Est-il possible d'avoir la liste des champs/méthodes privés et protégés d'une classe ?
lien : Comment récupérer la liste des méthodes d'une classe ?
lien : API Reflection

Comment savoir si une méthode ou un champ est de classe ?
auteur : Ricky81
Il existe une classe dans java.lang.reflect appelée Modifier.
Cette classe gère l'ensemble des informations définies pour un champ ou une méthode, à savoir : la visibilité, l'attribut "constante" ainsi que le caractère statique. Ce sont essentiellement des méthodes de classe qui permettent de consulter ces caractéristiques à partir d'un entier.

// m est un objet de type Method int mod = m.getModifiers(); if(java.lang.reflect.Modifier.isStatic(mod)) { System.out.println("méthode statique"); }
lien : Comment connaître la signature d'une méthode ?
lien : Comment déterminer l'ensemble des informations concernant un champ ?
lien : API Reflection

Comment déterminer l'ensemble des informations concernant un champ ?
auteur : Ricky81
Il existe bien entendu les méthodes getName() et getType() qui renvoie des le nom et le type du champ. Une dernière méthode permet d'obtenir les informations complémentaires : getModifiers(). Nous nous retrouvons avec un entier qu'il faut analyser à l'aide de la classe java.lang.reflect.Modifier. Nous allons ici utiliser la méthode statique toString() pour obtenir ces informations sous la forme d'une chaîne de caractères.

// f est un objet de type Field int mod = f.getModifiers(); System.out.println(java.lang.reflect.Modifier.toString(mod));
lien : Comment connaître la signature d'une méthode ?
lien : API Reflection

Comment accéder dynamiquement à la valeur d'un champ donné d'un objet ?
auteur : Ricky81
Pour consulter ou modifier un champ donné d'un objet de façon dynamique, il faut commencer par récupérer l'objet de type Field correspondant au champ en question. Il suffit ensuite d'appeler la méthode correspondante avec pour premier paramètre l'objet cible.
Prenons l'exemple suivant où nous modifions le contenu du champ défini par la variable nomChamp de l'objet obj en lui donnant la valeur définie par la variable val.

void changeValeur(Object obj, String nomChamp, Object val) throws Exception { java.lang.reflect.Field f = obj.getClass().getField(nomChamp); f.set(obj,val); }
Un exemple de consultation de la valeur d'un champ donné :

void afficheValeur(Object obj, String nomChamp) throws Exception { Field f = obj.getClass().getField(nomChamp); System.out.println(f.get(obj)); }
Remarque : les methodes set et get sont des méthodes générales mais il existe aussi des équivalents pour les types classiques : setDouble(Object obj, double d) ou setBoolean(Object obj, boolean z).

lien : Comment lancer dynamiquement une méthode donnée d'un objet ?
lien : Est-il possible d'avoir la liste des champs/méthodes privés et protégés d'une classe ?
lien : Y a-t-il un moyen de consulter et/ou de modifier la valeur d'un champ privé ?
lien : API Reflection

Comment lancer dynamiquement une méthode donnée d'un objet ?
auteur : Ricky81
Nous allons utiliser la méthode invoke définie dans la classe Method :

Object invoke(Object obj, Object[] args)
Voici un exemple générique de lancement dynamique d'une méthode donnée sur un objet :

Object lancerMethode(Object obj, 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 = obj.getClass().getMethod(nomMethode,paramTypes); return m.invoke(obj,args); }
lien : Comment lancer dynamiquement une méthode de classe donnée ?
lien : Comment accéder dynamiquement à la valeur d'un champ donné d'un objet ?
lien : Comment passer les types primitifs en paramètre lors de l'utilisation de la réflexivité ?
lien : API Reflection

Comment passer les types primitifs en paramètre lors de l'utilisation de la réflexivité ?
auteur : bulbo
Les types primitifs (byte, char, short, int, long, float, double, boolean) ont tous des wrapper dans le package java.lang. Respectivement: Byte, Character, Short, Integer, Long, Float, Double, Boolean.

Chacune de ces classes contient une variable static TYPE de type Class. C'est cette classe qu'il faut utiliser pour spécifier le type du paramètre; la valeur quand a elle sera contenue dans un objet du type du wrapper.

Exemple: Appel d'une méthode prenant un int en paramètre.

Dans cet exemple nous allons appeler la méthode statique abs(int) de la classe java.lang.Math

Class types[] = { Integer.TYPE }; Method method = Math.class.getMethod("abs", types); Object parametres[] = { new Integer(-1) }; Integer iWrap = (Integer) method.invoke(null, parametres); System.out.println("Valeur absolue de -1 = " + iWrap);
lien : Comment lancer dynamiquement une méthode donnée d'un objet ?
lien : API Reflection

Comment lancer dynamiquement une méthode de classe donnée ?
auteur : Ricky81
Pour lancer dynamiquement une méthode de classe, le principe est le même que pour une méthode sur un objet (voir lien). La signature de la méthode (classe Method) à utiliser étant :

Object invoke(Object obj, Object[] args)
Lorsque la méthode est de classe, le paramètre obj n'est pas évalué. Vous pouvez mettre n'importe quel objet ou tout simplement null.

lien : Comment lancer dynamiquement une méthode donnée d'un objet ?
lien : Comment savoir si une méthode ou un champ est de classe ?
lien : API Reflection

Y a-t-il un moyen de consulter et/ou de modifier la valeur d'un champ privé ?
auteur : Ricky81
Après avoir récupéré un objet sur un champ privé (voir lien), vous pouvez tenter de désactiver la protection en utilisant la méthode setAccessible(boolean b). Si l'utilisation de cette méthode ne provoque pas le déclenchement d'une exception par un SecurityManager, vous allez pouvoir modifier la valeur du champ.

Exemple : prenons une classe Secret avec un champ privé priv de type String.

void modifierChamp(Secret s, String val) { Field f = s.getClass().getDeclaredField("priv"); f.setAccessible(true); f.set(s,val); }
lien : Est-il possible d'avoir la liste des champs/méthodes privés et protégés d'une classe ?
lien : API Reflection

Est-il possible d'avoir la liste des champs/méthodes privés et protégés d'une classe ?
auteur : Ricky81
Les moyens mis à disposition par l'API Reflection permettent de passer outre les règles de l'encapsulation. Vous pourrez consulter les champs et méthodes privés/protégés de la même manière que les champs et méthodes publiques, mais en utilisant les méthodes getDeclaredFields et getDeclaredMethods (ainsi que leurs variantes) au lieu de getFields et getMethods.

Exemple :

Class c = Class.forName("maClasse"); java.lang.reflect.Field[] f = c.getDeclaredFields();
Remarque : contrairement aux méthodes getFields et getMethods, getDeclaredFields et getDeclaredMethods ne renvoient pas les informations héritées. Dans ce cas, il est nécessaire d'aller interroger la classe mère.

lien : Y a-t-il un moyen de consulter et/ou de modifier la valeur d'un champ privé ?
lien : API Reflection


Consultez les autres F.A.Q's

Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs.

Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs :

- Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement :
"Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement".

- Pour ce qui est des autres contributions : Copyright © 2004 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peux en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vos questions techniques : forum d'entraide PHP - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright 2000..2004 www.developpez.com