Les instances de la classe Class représentent des objets, dits descripteurs de classe, qui sont créés automatiquement par la Machine Virtuelle Java lors du chargement des classes durant l'exécution d'un programme.
Les instances de la classe Class représentent des objets, dits descripteurs de classe, qui sont créés automatiquement par la Machine Virtuelle Java lors du chargement des classes durant l'exécution d'un programme.
Toutes les classes Java héritant de la superclasse racine java.lang.Object hérite d'une méthode getClass() chargée de retourner l'objet Class de l'instance de classe courante.
LinkedList liste = new LinkedList(); Class classe = liste.getClass();
Cette classe ne possède pas de constructeurs, mais peut être instancier par l'intermédiaire de l'une des méthodes statiques ForName().
public class Introspection { public static void main(String[] args) { if (args.length > 0){ try { Class classe = Class.forName(args[0]); System.out.println("Le nom de la classe = " + classe.getName()); } catch (ClassNotFoundException e) { System.out.println("La classe n'a pu être déterminée !"); } } } }
La méthode forName() a pour fonction de charger dynamiquement une classe spécifiée sous la forme d'une chaîne de caractères. Cette méthode retourne un objet de type Class qui pourra être utilisé avec toutes les méthodes d'instance de la classe Class.
Class clsObjet = forName("java.lang.StringBuffer");
D'autre part, la classe Class contient essentiellement des méthodes capables de délivrer dynamiquement des informations relatives à une classe ou une interface cible.
La méthode getName() et toString() retournent le nom d'une classe ou d'une interface sous la forme d'une chaîne de caractères.
System.out.println(clsObjet.getName());
Si le type de la classe est un tableau, alors une chaîne de caractères spécifique est retournée par la méthode getName(). Cette chaîne de caractères débute par une séquence de caractère [ indiquant le nombre de dimensions du tableau. Puis une lettre représente le type primitif ou le type référence des éléments du tableau.
Caractère | Type | Exemple |
---|---|---|
B | représente un type byte. | byte[] t; [B |
C | représente un type char. | char[][] t; [[C |
D | représente un type double. | double[] t; [D |
F | représente un type float. | float[] t; [F |
I | représente un type int. | int[][][] t; [[[I |
J | représente un type long. | long[][] t; [[L |
LnomClasse; | représente une classe ou une interface. | Object[] t; [Ljava.lang.Object; |
S | représente un type short. | short[][][][] t; [[[[S |
Z | représente un type boolean. | boolean[] t; [Z |
Les méthodes getDeclaredFields(), getDeclaredConstructors(), getDeclaredMethods() permettent de retourner respectivement, tous les champs, les constructeurs et les méthodes déclarés par la classe ou l'interface cible.
Field[] tabChamps = clsObjet.getDeclaredFields(); Method[] tabMethodes = clsObjet.getDeclaredMethods(); Constructor[] tabConstructeurs = clsObjet.getDeclaredConstructors();
Les méthodes getFields(), getMethods() et getConstructors() ressemblent à celles précitées, mais à la différence qu'elles retournent essentiellement les champs, méthodes et constructeurs publics de la classe courante mais également de ses classes et interfaces parentes.
Field[] tabChamps = clsObjet.getFields(); Method[] tabMethodes = clsObjet.getMethods(); Constructor[] tabConstructeurs = clsObjet.getConstructors();
Le type référence des tableaux retournés par ces méthodes se trouvent dans le paquetage java.lang.Reflect. C'est à partir des classes appropriées de ce paquetage qu'il sera possible de manipuler ces objets.
import java.lang.Reflect;
L'obtention d'une méthode ou d'un constructeur individuel nécessite de renseigner son nom (essentiellement pour les méthodes) et ses éventuels types de paramètres au sein respectivement, des méthodes getMethod() ou getDeclaredMethod() ou getConstructor() ou getDeclaredConstructor(). Les types de paramètres doivent être fournis dans un tableau de classes. Par la suite, la méthode ou le constructeur pourra être respectivement invoquer ou instancier par l'objet courant correspondant de type Method ou Constructor.
Class classe = Class.forName("java.util.Hashtable"); Object obj = classe.newInstance(); Class[] types = { Class.forName("java.lang.Object"), Class.forName("java.lang.Object") }; Object[] params = {new Integer(0), "Une chaîne..."}; Method methode = classe.getMethod("put", types); methode.invoke(obj, params); Class classe = Class.forName("java.util.Hashtable"); Class[] types = {Integer.TYPE}; Constructor constructeur = classe.getConstructor("Hashtable", types); Object[] params = {new Integer(20)}; Object obj = constructeur.newInstance(params);
Plusieurs autres méthodes préfixées par get retournent le paquetage (getPackage()), la superclasse (getSuperClass), les modificateurs (getModifiers()), les classes imbriquées (getClasses()), les interfaces implémentées (getInterfaces()), le chargeur de classe (getClassLoader()) ou encore la classe de déclaration (getDeclaringClass()).
Plusieurs méthodes préfixées par is et retournant une valeur booléenne, permettent de vérifier le type des classes objets spécifiques. Les méthodes isArray() et isPrimitive() testent respectivement si la classe objet représente un tableau et un des huit types primitifs et void (Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE).
if(clsObjet.isArray()){ System.out.println("L'objet Class est un tableau !"); } elseif(clsObjet.isPrimitive()){ System.out.println("L'objet Class est un type primitif !"); } elseif(clsObjet.isInterface()){ System.out.println("L'objet Class est une interface !"); } else{ System.out.println("L'objet Class est une classe !"); }
En outre, d'autres méthodes de ce type permettent de déterminer si l'objet donné est une instance de cette classe (isInstance()), si le descripteur de classe représente une interface (IsInterface()) et si les objets d'une classe donnée peuvent être assignés aux objets de cette classe (isAssignableFrom()).
if(clsObjet.isInstance()){ //Bloc d'instructions... }
La méthode newInstance() est utilisée pour instancier la classe représentée par l'objet Class. Lors de la création de l'objet, le constructeur par défaut est appelé pour initialiser l'objet. L'objet retourné par la méthode newInstance() est de type Object.
Exemple [voir]Class clsVecteur = Class.forName("java.util.Vector"); // est équivalent à Vector vecteur = new Vector(); Vector vecteur = (Vector)(clsVecteur.newInstance());
public class Introspection { public static void main(String[] args) { String ch = new String("Une chaîne de caractères..."); if (args.length > 0){ try { Class classe = Class.forName(args[0]); System.out.println("Le nom de la classe = " + classe.getName()); System.out.println("Le paquetage de la classe = " + classe.getPackage().getName()); System.out.println("Le chargeur de classe = " + classe.getClassLoader()); System.out.println("Le superclasse de la classe = " + classe.getSuperclass()); System.out.println("Les méthodes publiques de la classe = " + classe.getMethods().length); System.out.println("Toutes les méthodes de la classe = " + classe.getDeclaredMethods().length); System.out.println("Les constructeurs publiques de la classe = " + classe.getConstructors().length); System.out.println("Tous les constructeurs de la classe = " + classe.getDeclaredConstructors().length); System.out.println("Les champs publiques de la classe = " + classe.getFields().length); System.out.println("Tous les champs de la classe = " + classe.getDeclaredFields().length); System.out.println("La classe est " + obtenirModificateurs(classe.getModifiers()) + "."); if(classe.isInstance(ch)){ System.out.println("L'objet ch est une instance de la classe sous-jacente."); } Vector tabParents = obtenirHierarchie(classe); String esp = ""; for(int i = tabParents.size() - 1; i >= 0; i--){ System.out.println(esp + tabParents.elementAt(i)); for(int j = 0; j < i; j++) esp += " "; } Class primitive = Boolean.TYPE; System.out.println("Le nom de la classe = " + primitive.getName()); System.out.println("Le paquetage de la classe = " + primitive.getPackage()); System.out.println("Le chargeur de classe = " + primitive.getClassLoader()); System.out.println("Le superclasse de la classe = " + primitive.getSuperclass()); if(primitive.isPrimitive()){ System.out.println("La classe sous-jacente " + "représente un type primitif."); } } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("La classe n'a pu être déterminée !"); } } } /** |