java reflection tutorial with examples
Ce didacticiel vidéo explique ce qu'est Reflection et comment l'implémenter à l'aide de l'API Reflection:
La réflexion en Java consiste à inspecter et à modifier le comportement d'un programme à l'exécution.
Avec l'aide de cette API de réflexion, vous pouvez inspecter les classes, les constructeurs, les modificateurs, les champs, les méthodes et les interfaces au moment de l'exécution. Par exemple, vous pouvez obtenir le nom de la classe ou vous pouvez obtenir des détails sur les membres privés de la classe.
Lisez l'ensemble de notre Série de formation JAVA pour plus d'informations sur les concepts Java.
Voici un didacticiel vidéo sur Java Reflection:
Ce que vous apprendrez:
- Réflexion en Java
- API Reflection en Java
- Classe java.lang.Class
- Créer des objets java.lang.Class
- Obtenez des modificateurs de super classe et d'accès
- Obtenir des interfaces
- Réflexion: obtenir la valeur du champ
- Réflexion: Méthode
- Réflexion: constructeur
- Inconvénients de la réflexion
- Questions fréquemment posées
- En savoir plus sur Java Reflection
- Conclusion
Réflexion en Java
Nous sommes conscients que dans une classe donnée, nous pouvons modifier ses propriétés et méthodes au moment de la compilation et c'est très facile de le faire. Que les propriétés et méthodes soient anonymes ou portent des noms, elles peuvent être modifiées à notre gré lors de la compilation.
Mais nous ne pouvons pas modifier ces classes, méthodes ou champs à la volée lors de l'exécution. En d'autres termes, il est très difficile de modifier le comportement de divers composants de programmation lors de l'exécution, en particulier pour les objets inconnus.
Le langage de programmation Java fournit une fonctionnalité appelée 'Réflexion' cela nous permet de modifier le comportement d'exécution d'une classe, d'un champ ou d'une méthode lors de l'exécution.
Ainsi, une réflexion peut être définie comme un «Technique d'inspection et de modification du comportement d'exécution d'un objet inconnu au moment de l'exécution. Un objet peut être une classe, un champ ou une méthode. »
Reflection est une «interface de programmation d'application» (API) fournie par Java.
Le processus de «réflexion» est décrit ci-dessous.

Dans la représentation ci-dessus, nous pouvons voir que nous avons un objet inconnu. Ensuite, nous utilisons l'API Reflection sur cet objet. En conséquence, nous pouvons modifier le comportement de cet objet lors de l'exécution.
Ainsi, nous pouvons utiliser l’API Reflection dans nos programmes dans le but de modifier le comportement de l’objet. Les objets peuvent être n'importe quoi comme des méthodes, des interfaces, des classes, etc. Nous inspectons ces objets puis modifions leur comportement à l'exécution à l'aide de l'API de réflexion.
En Java, «java.lang» et «java.lang.reflect» sont les deux packages qui fournissent des classes pour la réflexion. La classe spéciale «java.lang.Class» fournit les méthodes et propriétés pour extraire les métadonnées à l'aide desquelles nous pouvons inspecter et modifier le comportement de la classe.
Nous utilisons l'API Reflection fournie par les packages ci-dessus pour modifier la classe et ses membres, y compris les champs, les méthodes, les constructeurs, etc. au moment de l'exécution. Une caractéristique distinctive de l'API Reflection est que nous pouvons également manipuler les données membres privées ou les méthodes de la classe.
L'API Reflection est principalement utilisée dans:
- La réflexion est principalement utilisée dans les outils de débogage, JUnit et les frameworks pour inspecter et modifier le comportement lors de l'exécution.
- IDE (environnement de développement intégré) Par exemple. Eclipse IDE, NetBeans, etc.
- Outils de test, etc.
- Il est utilisé lorsque votre application possède des bibliothèques tierces et lorsque vous souhaitez connaître les classes et méthodes disponibles.
API Reflection en Java
À l'aide de l'API Reflection, nous pouvons implémenter la réflexion sur les entités suivantes:
- Domaine : La classe Field contient des informations que nous utilisons pour déclarer une variable ou un champ comme un type de données (int, double, String, etc.), un modificateur d'accès (privé, public, protégé, etc.), un nom (identifiant) et une valeur.
- Méthode : La classe Method peut nous aider à extraire des informations telles que le modificateur d'accès de la méthode, le type de retour de méthode, le nom de la méthode, les types de paramètres de méthode et les types d'exception déclenchés par la méthode.
- Constructeur : La classe Constructor fournit des informations sur le constructeur de classe qui inclut le modificateur d'accès au constructeur, le nom du constructeur et les types de paramètres.
- Modifier : La classe de modificateur nous donne des informations sur un modificateur d'accès spécifique.
Toutes les classes ci-dessus font partie du package java.lang.reflect. Ensuite, nous discuterons de chacune de ces classes et utiliserons des exemples de programmation pour démontrer la réflexion sur ces classes.
Commençons par la classe java.lang.Class.
Classe java.lang.Class
Java.lang.La classe contient toutes les informations et données sur les classes et les objets lors de l'exécution. C'est la classe principale utilisée pour la réflexion.
La classe java.lang.Class fournit:
- Méthodes pour récupérer les métadonnées de classe au moment de l'exécution.
- Méthodes pour inspecter et modifier le comportement d'une classe au moment de l'exécution.
Créer des objets java.lang.Class
Nous pouvons créer des objets de java.lang.Class en utilisant l'une des options suivantes.
quel est le meilleur anti-spyware
# 1) .class extension
La première option pour créer un objet de classe consiste à utiliser l'extension .class.
Par exemple,si Test est une classe, nous pouvons créer un objet Class comme suit:
Class obj_test = Test.class; Ensuite, nous pouvons utiliser obj_test pour effectuer une réflexion car cet objet aura toutes les informations sur la classe Test.
# 2) méthode forName ()
La méthode forName () prend le nom de la classe comme argument et renvoie l'objet Class.
Par exemple,l'objet de la classe Test peut être créé comme suit:
class obj_test = Class.forName (“Test”); # 3) Méthode getClas ()
La méthode getClass () utilise l'objet d'une classe pour obtenir l'objet java.lang.Class.
Par exemple,considérez le morceau de code suivant:
Test obj = new Test (); Class obj_test = obj.getClass (); Dans la première ligne, nous avons créé un objet de la classe Test. Ensuite, en utilisant cet objet, nous avons appelé la méthode «getClass ()» pour obtenir un objet obj_test de java.lang.Class.
Obtenez des modificateurs de super classe et d'accès
java.lang.class fournit une méthode «getSuperClass ()» qui est utilisée pour obtenir la superclasse de n'importe quelle classe.
De même, il fournit une méthode getModifier () qui renvoie le modificateur d'accès de la classe.
L'exemple ci-dessous illustre la méthode getSuperClass ().
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String() args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }Production

Dans l'exemple de programmation ci-dessus, une personne d'interface est définie avec une seule méthode «display ()». Ensuite, nous définissons une classe Student implémentant l'interface personne. Dans la méthode principale, nous utilisons la méthode getClass () pour récupérer l'objet Class, puis accéder au parent ou à la superclasse de l'objet Student en utilisant la méthode getSuperClass ().
Obtenir des interfaces
Si la classe implémente certaines interfaces, nous pouvons obtenir ces noms d'interfaces à l'aide de la méthode getInterfaces () de java.lang.Class. Pour cela, nous devons effectuer une réflexion sur la classe Java.
L'exemple de programmation ci-dessous décrit l'utilisation de la méthode getInterfaces () dans Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String() args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class() objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }Production

Dans le programme ci-dessus, nous avons défini deux interfaces, à savoir Animals et PetAnimals. Ensuite, nous définissons une classe Dog, qui implémente ces deux interfaces.
Dans la méthode principale, nous récupérons l'objet de la classe Dog dans java.lang.Class pour effectuer la réflexion. Ensuite, nous utilisons la méthode getInterfaces () pour récupérer les interfaces implémentées par la classe Dog.
Réflexion: obtenir la valeur du champ
Comme déjà mentionné, le package java.lang.reflect fournit la classe Field qui nous aide à refléter le champ ou les données membres de la classe.
Vous trouverez ci-dessous les méthodes fournies par la classe Field pour la réflexion d'un champ.
| Méthode | La description |
|---|---|
| getField ('fieldName') | Renvoie le champ (public) avec un nom de champ spécifié. |
| getFields () | Renvoie tous les champs publics (à la fois pour la classe et la superclasse). |
| getDeclaredFields () | Récupère tous les champs de la classe. |
| getModifier () | Renvoie une représentation entière du modificateur d'accès du champ. |
| set (classObject, valeur) | Attribue la valeur spécifiée au champ. |
| get (classObject) | Récupère la valeur du champ. |
| setAccessible (booléen) | Rendre le champ privé accessible en passant true. |
| getDeclaredField ('fieldName') | Renvoie le champ avec un nom spécifié. |
Ci-dessous, deux exemples de réflexion qui démontrent la réflexion sur le domaine public et privé.
Le programme Java ci-dessous montre la réflexion sur un champ public.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String() args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }Production

Dans ce programme, nous avons déclaré une classe «Student» ayant un champ public StudentName. Ensuite, à l'aide de l'interface API de la classe Field, nous effectuons une réflexion sur le champ StudentName et récupérons son modificateur d'accès et sa valeur.
Le programme suivant effectue une réflexion sur un champ privé de la classe. Les opérations sont similaires sauf qu'il y a un appel de fonction supplémentaire effectué pour le champ privé. Nous devons appeler setAccessible (true) pour le champ privé. Ensuite, nous effectuons une réflexion sur ce domaine de manière similaire au domaine public.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String() args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }Production

Réflexion: Méthode
Semblable aux champs de la classe, nous pouvons également effectuer une réflexion sur les méthodes de classe et modifier leur comportement à l'exécution. Pour cela, nous utilisons la classe Method du package java.lang.reflect.
Vous trouverez ci-dessous les fonctions fournies par la classe Method pour la réflexion de la méthode de classe.
| Méthode | La description |
|---|---|
| getMethods () | Récupère toutes les méthodes publiques définies dans la classe et sa superclasse. |
| getDeclaredMethod () | Renvoie les méthodes déclarées dans la classe. |
| getName () | Renvoie les noms des méthodes. |
| getModifiers () | Renvoie une représentation entière du modificateur d'accès de la méthode. |
| getReturnType () | Renvoie le type de retour de la méthode. |
L'exemple ci-dessous montre le reflet des méthodes de classe en Java utilisant les API ci-dessus.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String() args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method() methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }Production

Dans le programme ci-dessus, nous voyons que la méthode getDeclaredMethods retourne le tableau des méthodes déclarées par la classe. Ensuite, nous parcourons ce tableau et affichons les informations de chaque méthode.
Réflexion: constructeur
Nous pouvons utiliser la classe «Constructor» du package java.lang.reflect pour inspecter et modifier les constructeurs d'une classe Java.
La classe constructeur fournit les méthodes suivantes à cet effet.
| Méthode | La description |
|---|---|
| getConstructors () | Renvoie tous les constructeurs déclarés dans la classe et sa superclasse. |
| getDeclaredConstructor () | Renvoie tous les constructeurs déclarés. |
| getName () | Récupère le nom du constructeur. |
| getModifiers () | Renvoie la représentation entière du modificateur d'accès des constructeurs. |
| getParameterCount () | Renvoie le nombre total de paramètres pour un constructeur. |
L'exemple de réflexion ci-dessous illustre le reflet des constructeurs d'une classe en Java. Comme la réflexion de méthode, ici aussi la méthode getDeclaredConstructors retourne un tableau de constructeurs pour une classe. Ensuite, nous parcourons ce tableau de constructeurs pour afficher des informations sur chaque constructeur.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String() args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor() constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class() paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }Production

Inconvénients de la réflexion
La réflexion est puissante, mais ne doit pas être utilisée sans discernement. S'il est possible d'opérer sans utiliser la réflexion, il est préférable d'éviter de l'utiliser.
Voici quelques inconvénients de Reflection:
- Frais généraux de performance: Bien que la réflexion soit une fonction puissante, les opérations réfléchissantes ont toujours des performances plus lentes que les opérations non réfléchissantes. Par conséquent, nous devons éviter d'utiliser les réflexions dans les applications critiques pour les performances.
- Restrictions de sécurité: La réflexion étant une fonctionnalité d'exécution, elle peut nécessiter des autorisations d'exécution. Ainsi, pour les applications qui nécessitent que le code soit exécuté dans un paramètre de sécurité restreint, la réflexion peut être inutile.
- Exposition des composants internes: En utilisant la réflexion, nous pouvons accéder aux champs privés et aux méthodes d'une classe. Ainsi, la réflexion rompt l'abstraction qui pourrait rendre le code non portable et dysfonctionnel.
Questions fréquemment posées
Q # 1) Pourquoi Reflection est-il utilisé en Java?
Répondre: En utilisant la réflexion, nous pouvons inspecter les classes, les interfaces, les constructeurs, les champs et les méthodes au moment de l'exécution, même s'ils sont anonymes au moment de la compilation. Cette inspection nous permet de modifier le comportement de ces entités lors de l'exécution.
Q # 2) Où Reflection est-il utilisé?
Répondre: La réflexion est utilisée dans l'écriture de frameworks qui interagissent avec des classes définies par l'utilisateur, dans lesquelles le programmeur ne sait même pas ce que seront les classes ou autres entités.
Q # 3) Java Reflection est-il lent?
Répondre: Oui, il est plus lent que le code de non-réflexion.
Q # 4) La réflexion Java est-elle mauvaise?
Répondre: D'une certaine manière, oui. Tout d'abord, nous perdons la sécurité lors de la compilation. Sans sécurité au moment de la compilation, nous pourrions obtenir des erreurs d'exécution susceptibles d'affecter les utilisateurs finaux. Il sera également difficile de déboguer l'erreur.
Q # 5) Comment arrêter une réflexion en Java?
Répondre: Nous évitons simplement d'utiliser la réflexion en écrivant des opérations de non-réflexion. Ou peut-être pouvons-nous utiliser des mécanismes génériques comme une validation personnalisée avec réflexion.
En savoir plus sur Java Reflection
Le package java.lang.reflect a les classes et les interfaces pour faire la réflexion. Et le java.lang.class peut être utilisé comme point d'entrée pour la réflexion.
Comment obtenir les objets de classe:
1. Si vous avez une instance d'un objet,
classe c = obj.getclass ();
2. Si vous connaissez le type de cours,
classe c = type.getClass ();
3. Si vous connaissez le nom de la classe,
Classe c = Class.forName ('com.demo.Mydemoclass');
Comment obtenir les membres de la classe:
Les membres de classe sont des champs (variables de classe) et des méthodes.
- getFields () - Utilisé pour obtenir tous les champs sauf les champs privés.
- getDeclaredField () - Utilisé pour obtenir les champs privés.
- getDeclaredFields () - Utilisé pour obtenir les champs privé et public.
- getMethods () - Utilisé pour obtenir toutes les méthodes à l'exception des méthodes privées.
- getDeclaredMethods () –Utilisé pour obtenir les méthodes publiques et privées.
Programmes de démonstration:
ReflectionHelper.java:
C'est la classe que nous allons inspecter à l'aide de l'API de réflexion.
meilleurs sites Web pour regarder des anime gratuitement
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } } 
ReflectionDemo.java
public class ReflectionDemo { public static void main(String() args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field() fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field() privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method() methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}

Conclusion
Ce didacticiel a expliqué en détail l'API Reflection en Java. Nous avons vu comment effectuer la réflexion des classes, des interfaces, des champs, des méthodes et des constructeurs avec quelques inconvénients de réflexion.
La réflexion est une fonctionnalité relativement avancée en Java, mais devrait être utilisée par les programmeurs ayant une place forte sur le langage. En effet, cela peut entraîner des erreurs et des résultats inattendus s'il n'est pas utilisé avec prudence.
Bien que la réflexion soit puissante, elle doit être utilisée avec précaution. Néanmoins, en utilisant la réflexion, nous pouvons développer des applications qui ne connaissent pas les classes et autres entités jusqu'à l'exécution.
=> Jetez un œil au guide du débutant Java ici.
lecture recommandée
- Tutoriel de classe de scanner Java avec des exemples
- Classe Java Integer et Java BigInteger avec exemples
- Tutoriel JAVA pour les débutants: plus de 100 tutoriels vidéo Java pratiques
- Introduction au langage de programmation Java - Tutoriel vidéo
- Qu'est-ce que le vecteur Java | Tutoriel de classe vectorielle Java avec des exemples
- Tutoriel sur l'interface Java et la classe abstraite avec des exemples
- Méthode Java substring () - Tutoriel avec des exemples
- Tutoriel Java Collections Framework (JCF)