Vous êtes sur la page 1sur 11

Java et la rflexivit

Informations sur le tutoriel


Auteur : cysboy Difficult : Licence : Plus d'informations

Popularit
Visualisations : 2 073 756 Apprciation 46 des lecteurs :42 68 443 2716 personnes souhaitent voir ce tutoriel publi en livre ! Vous aussi ?

Publicit Historique des mises jour


Le 21/02/2011 16:43:27 Correction orthographique suite au report #3935 Le 17/02/2011 05:58:52 Correction orthographique #3911 Le 07/02/2011 12:09:18 Correction d'une faute de syntaxe.

Partager
Imprimer Convertir en PDF Email Twitter Facebook Plus de services Voici un chapitre qui, je pense, ne vous servira pas tout de suite. Cependant, il me semble important d'en parler... La rflexivit n'est en fait que le moyen de connatre toutes les informations concernant une classe donne. Vous pourrez mme crer des instances de classe de faon dynamique grce ceci. Je pense faire une partie sur les design pattern aprs celle sur les interfaces graphiques ! Et, ce moment, vous aurez sans doute besoin des connaissances de ce chapitre, surtout lorsque nous aborderons le pattern factory. En attendant, je pense que ce chapitre va tout de mme vous intresser !

Alors, allons-y... Sommaire du chapitre :

Commenons par le commencement Interroger un objet Class Instanciation dynamique Ce qu'il faut retenir

Commenons par le commencement


La rflexivit, aussi appele introspection, consiste dcouvrir de faon dynamique des informations propres une classe Java ou un objet. Ceci est notamment utilis au niveau de la machine virtuelle Java lors de l'excution de votre programme. En gros, votre machine virtuelle stocke les informations relatives une classe dans un objet.

Concrtement, que se passe-t-il ?


Au chargement d'une classe Java, votre JVM cre automatiquement un objet. Celui-ci rcupre toutes les caractristiques de votre classe ! Il s'agit d'un objet Class. Exemple: si vous avez cr trois nouvelles classes Java, l'excution de votre programme, la JVM va crer un objet Class pour chacune d'elles. Comme vous devez vous en douter, cet objet possde une multitude de mthodes qui permettent d'avoir tous les renseignements possibles et imaginables sur une classe. Dans ce chapitre, nous allons visiter la classe String. Crez un nouveau projet ainsi qu'une classe contenant la mthode main. Voici deux faons de rcuprer un objet Class : Code : Java - Slectionner public class Test { public static void main(String[] args) { Class c = String.class; Class c2 = new String().getClass(); /*La fameuse mthode finale dont je vous parlais dans le chapitre sur l'hritage Cette mthode vient de la classe Object */ } }

Maintenant que vous savez rcuprer un objet Class, nous allons tout de suite voir ce qu'il sait faire !

Interroger un objet Class


Dans ce sous-chapitre, nous allons voir une partie des choses que sait faire un objet Class. Je ne vais pas tout vous montrer... De toute faon, je pense que vous tes mme de chercher et de trouver tous seuls maintenant. Vous avez l'habitude de manipuler des objets, prsent...

Connatre la super classe d'une classe


Ce qui nous donne :

La classe Object n'a pas de super-classe... Voyez plutt :

Connatre la liste des interfaces


Vous pouvez tester ce code : Code : Java - Slectionner

public class Test { public static void main(String[] args) { //On rcupre un objet Class Class c = new String().getClass(); //La mthode getInterfaces retourne un tableau de Class Class[] faces = c.getInterfaces(); //Pour voir le nombre d'interfaces System.out.println("Il y a " + faces.length + " interfaces implmentes"); //On parcourt le tableau d'interfaces for(int i = 0; i < faces.length; i++) System.out.println(faces[i]); } }

Ce qui nous donne :

Connatre la liste des mthodes de la classe


La mthode getMethods() de l'objet Class nous retourne un tableau d'objets Method prsents dans le package java.lang.reflect. Vous pouvez soit faire l'import la main, soit dclarer un tableau d'objets Method et utiliser le raccourci Ctrl + Shift + O. Voici un code qui retourne la liste des mthodes de la classe String : Code : Java - Slectionner import java.lang.reflect.Method; public class Test { public static void main(String[] args) { Class c = new String().getClass(); Method[] m = c.getMethods(); System.out.println("Il y a " + m.length + " mthodes dans cette classe"); //On parcourt le tableau de mthodes for(int i = 0; i < m.length; i++) System.out.println(m[i]); } } Voici un morceau du rsultat car, comme vous pourrez le voir, il y a beaucoup de mthodes dans la classe String.

Vous pouvez constater que l'objet Method regorge lui aussi de mthodes intressantes. Voici un code qui affiche la liste des mthodes ainsi que la liste des attributs qu'elles prennent : Code : Java - Slectionner import java.lang.reflect.Method; public class Test { public static void main(String[] args) { Class c = new String().getClass(); Method[] m = c.getMethods(); System.out.println("Il y a " + m.length + " mthodes dans cette classe"); //On parcourt le tableau de mthodes for(int i = 0; i < m.length; i++) { System.out.println(m[i]); Class[] p = m[i].getParameterTypes(); for(int j = 0; j < p.length; j++) System.out.println(p[j].getName()); System.out.println("----------------------------------------\n"); } } }

Et voil :

Connatre la liste des champs (variable de classe ou d'instance) de la classe


Ici, nous allons appliquer la mme mthodologie que pour la liste des mthodes sauf que cette fois, la mthode invoque retourne un tableau d'objets Field. Voici un code qui affiche la liste des champs de la classe String. Code : Java - Slectionner import java.lang.reflect.Field; public class Test { public static void main(String[] args) { Class c = new String().getClass(); Field[] m = c.getFields(); System.out.println("Il y a " + m.length + " champs dans cette classe"); //On parcourt le tableau de mthodes for(int i = 0; i < m.length; i++) System.out.println(m[i].getName()); } }

Connatre la liste des constructeurs de la classe


Ici, nous utiliserons un objet Constructor pour lister les constructeurs de la classe : Code : Java - Slectionner

import java.lang.reflect.Constructor; public class Test { public static void main(String[] args) {

Class c = new String().getClass(); Constructor[] construc = c.getConstructors(); System.out.println("Il y a " + construc.length + " constructeurs dans cette cla //On parcourt le tableau des constructeur for(int i = 0; i < construc.length; i++){ System.out.println(construc[i].getName()); Class[] param = construc[i].getParameterTypes(); for(int j = 0; j < param.length; j++) System.out.println(param[j]); System.out.println("------------------------------------\n"); } } }

Vous pouvez donc constater que l'objet Class regorge de mthodes en tout genre ! Maintenant, si nous essayons d'exploiter un peu plus celles-ci...

Instanciation dynamique
Nous allons voir une petite partie de la puissance de cette classe (pour l'instant). Dans un premier temps, crez un nouveau projet avec une mthode main, ainsi qu'une classe correspondant ceci :

Voici son code Java : Code : Java - Slectionner

public class Paire { private String valeur1, valeur2; public Paire(){ this.valeur1 = null; this.valeur2 = null; System.out.println("Instanciation ! !"); } public Paire(String val1, String val2){ this.valeur1 = val1; this.valeur2 = val2; System.out.println("Instanciation avec des paramtres ! !"); } public String toString(){ return "Je suis un objet qui a pour valeur : " + this.valeur1 + " - " + } public String getValeur1() { return valeur1; } public void setValeur1(String valeur1) { this.valeur1 = valeur1; } public String getValeur2() { return valeur2; } public void setValeur2(String valeur2) { this.valeur2 = valeur2; } }

Le but du jeu maintenant consiste crer un objet Paire sans utiliser l'oprateur new. Pour instancier un nouvel objet Paire, nous allons tout d'abord rcuprer ses constructeurs. Ensuite, nous allons prparer un tableau contenant les donnes insrer. Puis nous invoquerons la mthode toString(). Regardez comment procder ; par contre, il y a moultes exceptions : Code : Java - Slectionner

import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) { String nom = Paire.class.getName();

try { //On cre un objet Class Class cl = Class.forName(nom); //Nouvelle instance de la classe Paire Object o = cl.newInstance();

//On cre les paramtres du constructeur Class[] types = new Class[]{String.class, String.class}; //On rcupre le constructeur avec les deux paramtres Constructor ct = cl.getConstructor(types); //On instancie l'objet avec le constructeur surcharg ! Object o2 = ct.newInstance(new String[]{"valeur 1 ", "valeur 2" } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

Et le rsultat donne :

Nous pouvons maintenant appeler la mthode toString() du deuxime objet... oh et soyons fous, sur les deux : Code : Java - Slectionner

import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { String nom = Paire.class.getName();

try { //On cre un objet Class Class cl = Class.forName(nom); //Nouvelle instance de la classe Paire Object o = cl.newInstance();

//On cre les paramtres du constructeur Class[] types = new Class[]{String.class, String.class}; //On rcupre le constructeur avec les deux paramtres Constructor ct = cl.getConstructor(types); //On instancie l'objet avec le constructeur surcharg ! Object o2 = ct.newInstance(new String[]{"valeur 1 ", "valeur 2"

//On va chercher la mthode toString, elle n'a aucun paramtre Method m = cl.getMethod("toString", null); //La mthode invoke excute la mthode sur l'objet pass en par // pas de paramtre, donc null en deuxime paramtre de la mth

System.out.println("------------------------------------------System.out.println("Mthode " + m.getName() + " sur o2: " System.out.println("Mthode " + m.getName() + " sur o: " } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

Et le rsultat

Voil : nous venons de crer deux instances d'une classe sans passer par l'oprateur new. Mieux encore ! Car nous avons mme pu appeler une mthode de nos instances ! Je ne vais pas m'attarder trop longtemps sur ce sujet... Mais gardez en tte que cette faon de faire, mme si elle est trs lourde, pourrait vous tre utile. Et l, je repense mon pattern factory. En quelques mots, il s'agit d'une classe Java qui ne fait que crer des instances ! Bon. Je crois que vous avez bien mrit une pause. Les deux derniers chapitres ont t assez prouvants... Un petit topo et en route pour la partie 3 !

Ce qu'il faut retenir


Lorsque votre JVM interprte votre programme, elle cre automatiquement un objet Class pour chaque classe charge. Avec un tel objet, vous pouvez connatre absolument tout sur votre classe. L'objet Class utilise des sous-objets comme Method, Field, Constructor... qui permettent de travailler avec vos diffrents objets, mais aussi avec ceux prsents dans Java. Avec cet objet, vous pouvez crer des instances de vos classes Java sans utiliser new. Par contre, vous devez savoir que les performances restent mdiocres.

Allez : je vous fais grce d'un QCM... Une fois n'est pas coutume ! Voil, c'tait le dernier chapitre de cette partie ! Il y a eu pas mal de choses vues ici... Je ne vais faire de long discours maintenant que vous tes si prs de la programmation vnementielle... Alors... Rendez-vous dans la troisime partie.

Vous aimerez peut-être aussi