1. Introduction
Java Reflection est un mécanisme qui nous permet d'obtenir des informations internes sur les méthodes de classe, les propriétés, les classes de parents, les interfaces, etc. au moment de l'exécution. En d'autres termes, la réflexion est essentiellement un processus "inverse". Lorsque nous créons une instance d'une classe via new , il est en fait construit par la machine virtuelle Java basée sur Class de cette classe lors de l'exécution, et la réflexion est d'obtenir ses informations de définition via Class d'une classe, afin que nous puissions accéder à ses propriétés et méthodes, connaître la classe parent de cette classe, que les interfaces sont implémentées et d'autres informations.
2. Classe
Nous savons que l'utilisation de Javac peut compiler des fichiers .java dans des fichiers .class, qui contiennent nos informations de définition d'origine pour la classe (classe parent, interface, constructeur, propriétés, méthodes, etc.). Le fichier .class sera chargé dans la machine virtuelle Java (JVM) ClassLoader lors de l'exécution. Lorsqu'un fichier .class est chargé, le JVM générera un objet de classe pour cela. Les objets que nous instancions via Nouveau dans le programme sont en fait construits en fonction de l'objet de classe correspondant à l'exécution. Pour être précis, cet objet de classe est en fait une instance de java.lang.Class<T> . Par exemple, Class<MyClass> est une instance Class<T> qui résume les informations de définition de MyClass . Étant donné que java.lang.Class<T> n'a pas de constructeur public, nous ne pouvons pas instancier directement cette classe. Nous pouvons obtenir un objet de classe via la méthode suivante.
Dans l'explication suivante, nous prendrons les cours de classe et d'élève des gens comme exemples:
classe publique People {Nom de chaîne privée; Âge privé; Les gens publics (nom de chaîne, int age) {this.name = name; this.age = âge; } public int getage () {return âge; } public String getName () {Nom de retour; } public void Setage (int Age) {this.age = age; } public void setName (string name) {this.name = name; } public void Speak () {System.out.println (getName () + "" + getage ()); }} classe publique étudiant étend les gens {private int gras; Étudiant public (nom de la chaîne, Int Age) {super (nom, âge); } Public Student (nom de chaîne, Int Age, int gras) {super (nom, âge); this.grade = grade; } public int getgrade () {return grade; } public void setgrade (int grade) {this.grade = grade; } private void Learn (cours de chaîne) {System.out.println (nom + "Learn" + cours); }} Obtenez un objet de classe par nom de classe
Si nous connaissons le nom d'une classe pendant la période de compilation, nous pouvons obtenir son objet de classe comme ceci:
Classe <Ople> PeopleClass = People.class;
Il existe également une méthode pour obtenir des objets de classe basés sur le nom de chemin complet de la classe comme suit:
// Supposons que la classe People se trouve dans la classe de package com.test <o,Ople> peupleclass = class.forname ("com.test.people"); Notez que le paramètre de Class.forName() doit être le nom de chemin complet d'une classe. En fait, tant que nous «importons com.test.people», nous pouvons directement obtenir son objet de classe via « People.class » sans avoir à écrire le chemin complet. (Si la classe correspondante n'est pas trouvée dans classpath lors de l'appel Class.forName() , ClassNotFoundException sera lancée.)
Obtenez son objet de classe à travers l'objet lui-même
People People = New People ("Bill", 18); Classe <Ople> PeopleClass = People.getClass (); Obtenez le constructeur de la classe par réflexion
Une fois que nous avons obtenu l'objet de classe des People , nous pouvons obtenir les informations de définition d'origine de la classe People via cet objet de classe. Tout d'abord, obtenons l'objet constructeur de People . Avec cet objet constructeur, nous pouvons construire un objet People . Par exemple, nous pouvons ajouter le code suivant dans Student.java:
public static void main (String [] args) {class <overs> pclass = People.class; try {constructor <poary> constructor = pclass.getConstructor (string.class, int.class); People People = Constructor.Newinstance ("Bill", 18); obj.speak (); } catch (exception e) {}} Dans ce qui précède, nous appelons getConstructor pour obtenir un objet constructeur de People . Depuis le constructeur, nous voulons obtenir les paramètres formels de la String de type et int , nous passons dans String.class et int.class . Avec l'objet constructeur, nous pouvons appeler la méthode newInstance pour créer un objet people .
Notez que lorsque le Constructor , Method et les objets Field de la classe sont obtenus par réflexion, avant d'appeler les méthodes de ces objets, l'indicateur accessible de cet objet est défini sur true pour annuler la vérification d'accès du langage Java, ce qui peut améliorer la vitesse de réflexion. Comme indiqué dans le code suivant:
Constructor <Poora> Constructor = peupleclass.getConstructor (String.class, int.class); // Définissez la propriété accessible du constructeur sur Ture pour annuler Java Access Check Constructor.SetAccessible (true);
Obtenir des méthodes déclarées en classe par la réflexion
Obtenez la méthode déclarée dans la classe actuelle (à l'exclusion héritée de la classe parent)
Pour faire déclarer toutes les méthodes dans la classe actuelle, vous pouvez utiliser la fonction getDeclaredMethods en classe. Il obtiendra toutes les méthodes déclarées dans la classe actuelle (y compris les méthodes private , public , static et autres). Il renverra un tableau d'objets Method et chaque objet Method représente la méthode déclarée dans une classe. Pour obtenir la méthode spécifiée, vous pouvez appeler getDeclaredMethod(String name, Class...<T> parameterTypes) .
Comme indiqué dans le code suivant:
privé statique void showdeclaredMethods () {étudiant étudiant = nouveau étudiant ("Bill", 18); // obtient toutes les méthodes déclarées par la méthode de classe étudiante [] méthodes = student.getClass (). GetDeclaredMethods (); essayez {// obtenez l'objet LearnMethod (encapsulé la méthode Learn) LearnMethod = Student.getClass (). GetDeclaredMethod ("Learn", String.class); // Obtenez la liste des paramètres de la méthode d'apprentissage et imprimez-le de la classe <?> [] ParamClasses = LearnMethod.GetParameterTypes (); for (class <?> classe: paramclasses) {System.out.println ("Paramètres de la méthode d'apprentissage:" + class.getName ()); } // juger si la méthode d'apprentissage est privé System.out.println (LearnMethod.getName () + "est privé" + modificateur.isprivate (LearnMethod.getModifiers ())); // Appelez la méthode Learn LearnMethod.invoke (Student, "Java Reflection"); } catch (exception e) {}} Faire déclarer des méthodes publiques dans la classe actuelle et la classe parentale
Pour obtenir la classe actuelle et toutes les méthodes public déclarées dans la classe Parent, vous pouvez appeler la fonction getMethods , et pour obtenir une méthode public spécifiée, vous pouvez appeler la méthode getMethod . Veuillez consulter le code suivant:
private static void showMethods () {étudiant étudiant = nouveau étudiant ("mr.simple"); // Obtenez toutes les méthodes publiques (y compris l'élève lui-même et héritées de la classe parent) Méthode [] Methods = Student.getClass (). GetMethods (); Essayez {// Notez que seules les méthodes publiques peuvent être obtenues via GetMethod. Si vous essayez d'obtenir une méthode privée, une exception sera lancée. Méthode LearnMethod = Student.getClass (). GetMethod ("Learn", String.class); } catch (exception e) {}} Obtenez les attributs définis dans la classe par réflexion
Obtenir des attributs est similaire à l'obtention de méthodes, sauf que l'appel à getMethods() / getDeclaredMethods() est remplacé par un appel à getFields() / getDeclaredFields() .
Obtenez les attributs définis dans la classe actuelle (excluant les attributs hérités de la classe parent)
Pour faire défini tous les attributs dans la classe actuelle (y compris divers attributs tels que private , public , static , etc.), vous pouvez appeler la fonction getDeclaredFields de l'objet de classe; Pour obtenir les attributs spécifiés, vous pouvez appeler getDeclaredField .
Comme indiqué dans le code suivant:
Private Static Void showdeclaredFields () {étudiant étudiant = nouveau étudiant ("Bill", 18); // Obtenez tous les attributs définis dans le champ de classe actuel [] Fields = Student.getClass (). GetDeclaredFields (); essayez {// obtenez l'attribut spécifié Field NieldField = Student.getClass (). GetDeclaredField ("Grade"); // Obtenez le System Valeur d'attribut.out.println ("La note est:" + gradeField.getInt (étudiant)); // Définir la valeur d'attribut Gradefield.Set (Student, 10); } catch (exception e) {}} Obtenez les attributs publics définis dans la classe actuelle et la classe parentale
Pour faire défini toutes les propriétés public dans la classe actuelle et la classe parent, vous pouvez appeler la fonction getFields de Class . Pour obtenir une propriété public spécifiée, vous pouvez appeler getField , comme indiqué dans le code suivant:
Private static void showfields () {étudiant étudiant = nouveau étudiant ("Bill", 18); // Obtenez toutes les propriétés publiques de la classe actuelle et du champ de classe parent [] publicFields = Student.getClass (). GetFields (); } Réflexion pour obtenir la classe parent de la classe et l'interface implémentée par la classe
Obtenez la classe parentale
Appelez simplement la méthode getSuperClass de Class , comme indiqué dans le code suivant:
Student Student = New Student ("Bill", 18); Class <?> SuperClass = Student.getClass (). GetSuperClass (); Obtenez l'interface implémentée
Pour savoir quelles interfaces une classe implémente, appelez simplement la méthode getInterfaces de Class , comme indiqué dans le code suivant:
private static void showInterfaces () {étudiant étudiant = nouveau étudiant ("Bill", 19); Classe <?> [] Interfaces = student.getClass (). GetInterfaces ();}Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que cela sera utile à l'étude et au travail de chacun.