CodeGym /Cours /JAVA 25 SELF /Obtenir des informations sur les classes, les champs et l...

Obtenir des informations sur les classes, les champs et les méthodes

JAVA 25 SELF
Niveau 62 , Leçon 1
Disponible

1. Obtenir des informations sur les champs

Quelle est la différence entre getFields() et getDeclaredFields()

En Java, chaque classe possède des champs (fields) — des variables déclarées à l’intérieur de la classe. Grâce à la réflexion, nous pouvons connaître leurs noms, leurs types, leurs modificateurs d’accès (public/private), ainsi que les manipuler à l’exécution. Le point d’entrée principal est l’objet Class<?>.

Méthodes principales de la classe Class pour travailler avec les champs :

Méthode Ce que renvoie
getFields()
Un tableau de tous les champs public de la classe, de ses parents et de ses interfaces
getDeclaredFields()
Un tableau de tous les champs déclarés dans cette classe

Analogie : getFields() — c’est comme une visite uniquement des salles d’exposition (public), tandis que getDeclaredFields() inclut aussi les locaux techniques (private, protected, package-private).

Exemple : afficher tous les champs de la classe

Supposons que nous ayons la classe suivante :

public class Person {
    public String name;
    private int age;
    protected String email;
}

Récupérons des informations sur les champs :

import java.lang.reflect.Field;

Class<?> clazz = Person.class;

// Tous les champs public (y compris hérités)
System.out.println("Public fields:");
for (Field field : clazz.getFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

// Tous les champs déclarés (y compris private, uniquement ceux de la classe)
System.out.println("\nDeclared fields:");
for (Field field : clazz.getDeclaredFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

Résultat :

Public fields:
name : String

Declared fields:
name : String
age : int
email : String

Comment connaître les modificateurs d’un champ ?

Chaque champ (Field) possède des modificateurs (public/private/protected, static, final, etc.). On peut les obtenir via getModifiers() et les convertir en chaîne au moyen de Modifier :

import java.lang.reflect.Modifier;

for (Field field : clazz.getDeclaredFields()) {
    int mods = field.getModifiers();
    System.out.println(field.getName() + " : " + Modifier.toString(mods));
}

2. Obtenir des informations sur les méthodes

Méthodes getMethods() et getDeclaredMethods()

Les méthodes sont les actions qu’un objet peut effectuer. Grâce à la réflexion, on peut connaître les méthodes d’une classe, leurs paramètres, leurs types de retour, leurs modificateurs et leurs annotations.

Méthode Ce que renvoie
getMethods()
Toutes les méthodes public de la classe et de ses parents (y compris Object)
getDeclaredMethods()
Toutes les méthodes déclarées dans cette classe (y compris private)

Exemple : afficher toutes les méthodes de la classe

import java.lang.reflect.Method;

System.out.println("Public methods:");
for (Method method : clazz.getMethods()) {
    System.out.println(method.getName());
}

System.out.println("\nDeclared methods:");
for (Method method : clazz.getDeclaredMethods()) {
    System.out.println(method.getName());
}

Résultat (pour Person) :

Public methods:
getClass
hashCode
equals
toString
notify
notifyAll
wait
wait
wait

Declared methods:
(rien si Person n’a déclaré aucune méthode propre)

Ajoutons une méthode dans Person :

public class Person {
    public String name;
    private int age;
    protected String email;

    public void sayHello() {
        System.out.println("Hi!");
    }
}

À présent, getDeclaredMethods() l’affichera aussi.

Comment connaître les paramètres et le type de retour d’une méthode ?

for (Method method : clazz.getDeclaredMethods()) {
    System.out.print(Modifier.toString(method.getModifiers()) + " ");
    System.out.print(method.getReturnType().getSimpleName() + " ");
    System.out.print(method.getName() + "(");
    Class<?>[] params = method.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Sortie :

public void sayHello();

3. Obtenir des informations sur les constructeurs

Les constructeurs sont des méthodes spéciales utilisées pour créer des objets.

Méthode Ce que renvoie
getConstructors()
Tous les constructeurs public
getDeclaredConstructors()
Tous les constructeurs déclarés dans la classe

Exemple : afficher tous les constructeurs de la classe

import java.lang.reflect.Constructor;

System.out.println("Constructors:");
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
    System.out.print(clazz.getSimpleName() + "(");
    Class<?>[] params = constructor.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Si la classe ne déclare que le constructeur par défaut, il sera affiché également.

4. Annotations : comment savoir ce qui est appliqué à une classe, une méthode ou un champ

Les annotations sont des marqueurs spéciaux que l’on peut appliquer aux classes, méthodes, champs et paramètres. Avec la réflexion, on peut savoir quelles annotations possède un élément.

Récupérer les annotations

  • Pour une classe : clazz.getAnnotations()
  • Pour une méthode : method.getAnnotations()
  • Pour un champ : field.getAnnotations()

Exemple : vérifier la présence de l’annotation @Deprecated

for (Method method : clazz.getDeclaredMethods()) {
    if (method.isAnnotationPresent(Deprecated.class)) {
        System.out.println(method.getName() + " is @Deprecated");
    }
}

Exemple : afficher toutes les annotations de la classe

for (var annotation : clazz.getAnnotations()) {
    System.out.println(annotation);
}

5. Pratique : mini-programme pour analyser la structure d’une classe

Rassemblons tout et écrivons un petit utilitaire qui, à partir du nom d’une classe, affiche sa structure : champs, méthodes, constructeurs et annotations.

Exemple de code : ClassInspector

import java.lang.reflect.*;
import java.util.Scanner;

public class ClassInspector {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Saisissez le nom complet de la classe (par exemple, java.util.ArrayList) : ");
        String className = scanner.nextLine();

        Class<?> clazz = Class.forName(className);

        System.out.println("\n== Classe : " + clazz.getName() + " ==");

        // Annotations de la classe
        System.out.println("Annotations :");
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println("  " + annotation);
        }

        // Champs
        System.out.println("\nChamps :");
        for (Field field : clazz.getDeclaredFields()) {
            System.out.println("  " + Modifier.toString(field.getModifiers())
                    + " " + field.getType().getSimpleName()
                    + " " + field.getName());
        }

        // Méthodes
        System.out.println("\nMéthodes :");
        for (Method method : clazz.getDeclaredMethods()) {
            System.out.print("  " + Modifier.toString(method.getModifiers())
                    + " " + method.getReturnType().getSimpleName()
                    + " " + method.getName() + "(");
            Class<?>[] params = method.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }

        // Constructeurs
        System.out.println("\nConstructeurs :");
        for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
            System.out.print("  " + Modifier.toString(constructor.getModifiers())
                    + " " + clazz.getSimpleName() + "(");
            Class<?>[] params = constructor.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }
    }
}

Comment cela fonctionne-t-il ?

  • L’utilisateur saisit le nom complet de la classe (par exemple « java.util.ArrayList » ou sa propre classe).
  • Le programme charge la classe dynamiquement et affiche ses annotations, champs, méthodes et constructeurs.
  • Essayez avec les classes standard du JDK — vous verrez combien de choses intéressantes s’y cachent !

6. Astuces utiles et visualisation

Schéma visuel : ce que l’on peut apprendre sur une classe via la réflexion

graph TD
    A[Class<?>] --> B["getFields/getDeclaredFields"]
    A --> C[getMethods/getDeclaredMethods]
    A --> D[getConstructors/getDeclaredConstructors]
    A --> E[getAnnotations]
    B --> F[Field: type, nom, modificateurs]
    C --> G[Method: type de retour, paramètres]
    D --> H[Constructor: paramètres]
    E --> I["Annotation[]"]

Tableau : où trouver l’information

Ce que l’on veut savoir Comment l’obtenir via la réflexion
Tous les champs public
clazz.getFields()
Tous les champs déclarés
clazz.getDeclaredFields()
Toutes les méthodes public
clazz.getMethods()
Toutes les méthodes déclarées
clazz.getDeclaredMethods()
Tous les constructeurs public
clazz.getConstructors()
Tous les constructeurs déclarés
clazz.getDeclaredConstructors()
Annotations de la classe
clazz.getAnnotations()
Annotations d’une méthode/d’un champ
method.getAnnotations(), field.getAnnotations()
Modificateurs
Modifier.toString(field.getModifiers())

7. Erreurs typiques lors de l’utilisation de la réflexion

Erreur n° 1 : confondre getFields() et getDeclaredFields().
Si vous recherchez des champs private, utilisez getDeclaredFields(), et non getFields(). Le premier renvoie tous les champs déclarés dans la classe, tandis que le second — seulement les public (y compris hérités !).

Erreur n° 2 : ne pas gérer les exceptions checked.
De nombreuses méthodes de réflexion lèvent des exceptions (par exemple, ClassNotFoundException ou SecurityException). N’oubliez pas de les gérer ou de les déclarer dans la signature de la méthode.

Erreur n° 3 : ignorer les modificateurs d’accès.
L’accès aux private champs et méthodes n’est possible qu’après avoir appelé setAccessible(true), sinon une IllegalAccessException sera levée. Exemple :

Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // On autorise l’accès au champ private
int value = (int) field.get(person);

Erreur n° 4 : s’attendre à ne voir que ses propres méthodes/champs.
getMethods() et getFields() renvoient les membres public non seulement de la classe courante, mais aussi de tous ses parents, y compris Object. Cela peut surprendre si vous pensiez ne voir que ce que vous avez écrit vous-même.

Erreur n° 5 : vérifier la présence d’annotations de manière incorrecte.
Utilisez isAnnotationPresent() pour vérifier une annotation précise plutôt que d’itérer manuellement le tableau des annotations sans nécessité.

1
Mission
JAVA 25 SELF, niveau 62, leçon 1
Bloqué
Audit de l'appareil secret 🕵️
Audit de l'appareil secret 🕵️
1
Mission
JAVA 25 SELF, niveau 62, leçon 1
Bloqué
Catalogage des rituels anciens 📜
Catalogage des rituels anciens 📜
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION