0. Technologie de réflexion
La technologie Reflection est une partie importante de l’écosystème Java et est largement utilisée dans Spring et d’autres frameworks.
Grâce à la technologie de réflexion, nous pouvons : Pendant l'exécution du programme :
-
Construire un objet de n'importe quelle classe,
-
Comprendre la classe à laquelle appartient tout objet,
-
Apprenez toutes les variables et méthodes membres de n'importe quelle classe,
-
Appelez des propriétés et des méthodes dans n’importe quelle classe.
1. Méthode d'obtention
1.1. Créer une classe d'entité
Les classes d'entités contiennent des méthodes privées, des méthodes publiques, des variables privées et des variables publiques.
public class Student {
private String name;
private Integer age;
public String className;
public Student() {
}
private Student(String name) {
this.name = name;
}
public Student(Integer age) {
this.age = age;
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
private void getAge(){
System.out.println("这是一个私有方法");
}
public void getName(){
System.out.println("这是一个公有方法");
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setClassName(String className) {
this.className = className;
}
}
1.1. Obtenir la méthode de construction
1.1.1 Obtenir tous les constructeurs de la classe
Tout d'abord, vous devez obtenir l'objet de classe via la méthode mentionnée dans l'article précédent, puis getDeclaredConstructors()
obtenir tous les constructeurs de la classe via .
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
Constructor<?>[] constructors = student.getDeclaredConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
}
}
}
Les résultats de sortie sont les suivants :
public com.reflect.Student(java.lang.String,java.lang.Integer)
public com.reflect.Student (java.lang.Integer)
privé com.reflect.Student (java.lang.String)
public com.reflect.Student()
À partir des résultats de sortie, vous pouvez voir que les quatre constructeurs de la classe d'entité ont été obtenus, y compris un constructeur privé. Et la liste des paramètres du constructeur peut également être supprimée.
1.1.2 Obtenir tous les constructeurs publics
Différent de la méthode de réflexion qui obtient toutes les méthodes de construction, getConstructors()
il suffit de l'utiliser ici.
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
Constructor<?>[] constructors = student.getConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
}
}
}
Le résultat est le suivant :
public com.reflect.Student(java.lang.String,java.lang.Integer)
public com.reflect.Student (java.lang.Integer)
public com.reflect.Student()
Il n'y a pas de constructeur privé dans la classe, seulement des méthodes publiques.
1.1.3 Obtenir la méthode de construction correspondante selon la liste des paramètres
Si nous voulons obtenir un constructeur spécifique basé sur la liste de paramètres, nous pouvons utiliser getDeclaredConstructor()
la méthode qui spécifie les paramètres requis par le constructeur :
- Tous les paramètres doivent utiliser des objets de classe ;
- L'ordre des paramètres doit être cohérent avec l'ordre dans le constructeur ;
- Pour obtenir le constructeur sans argument, vous pouvez entrer null comme paramètre ou le laisser vide ;
- Cette méthode peut générer des exceptions qui ne peuvent pas être trouvées par la méthode, les exceptions doivent donc être interceptées ou levées.
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
try {
Class<Student> student = Student.class;
//获取私有构造方法
Constructor<?> constructor = student.getDeclaredConstructor(String.class);
System.out.println(constructor);
//获取公有构造方法
Constructor<?> constructor2 = student.getDeclaredConstructor(String.class, Integer.class);
System.out.println(constructor2);
//获取无参构造方法
Constructor<?> constructor3 = student.getDeclaredConstructor(null);
System.out.println(constructor3);
}catch (Exception e){
e.printStackTrace();
}
}
}
Le résultat de sortie est
privé com.reflect.Student (java.lang.String)
public com.reflect.Student(java.lang.String,java.lang.Integer)
public com.reflect.Student()
- Si vous souhaitez uniquement obtenir le constructeur de type public, vous pouvez utiliser
getConstructor()
la méthode.Lorsque le constructeur correspondant est privé, une exception sera rapportéejava.lang.NoSuchMethodException
; - Si la méthode correspondante n'est pas trouvée selon la liste des paramètres, le programme signalera une exception
java.lang.NoSuchMethodException
.
1.2. Obtenir des méthodes communes
1.2.1 Obtenir toutes les méthodes courantes
En utilisant l'objet de classe getDeclaredMethods()
, vous pouvez obtenir toutes les méthodes ordinaires (méthodes non constructeurs) sous la classe actuelle .
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
//获取所有方法
Method[] declaredMethods = student.getDeclaredMethods();
for (Method method : declaredMethods){
System.out.println(method);
}
}
}
Le résultat de sortie est
public void com.reflect.Student.getName()
public void com.reflect.Student.setName(java.lang.String)
vide privé com.reflect.Student.getAge()
public void com.reflect.Student.setAge(java.lang.Integer)
public void com.reflect.Student.setClassName(java.lang.String)
Des méthodes privées et publiques sont obtenues.
1.2.2 Obtenir toutes les méthodes ordinaires publiques
En utilisant l'objet de classe getMethods()
, vous pouvez obtenir toutes les méthodes courantes (méthodes non constructeurs) modifiées par public sous la classe actuelle et toutes les classes parentes .
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
//获取所有方法
Method[] declaredMethods = student.getMethods();
for (Method method : declaredMethods){
System.out.println(method);
}
}
}
Les résultats de sortie incluent toutes les méthodes modifiées par public sous la classe Student et la classe parent par défaut Object.
public void com.reflect.Student.getName()
public void com.reflect.Student.setName(java.lang.String)
public void com.reflect.Student.setAge(java.lang.Integer)
public void com.reflect.Student.setClassName(java.lang.String)
public final void java.lang.Object.wait() lance java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) lance java.lang.InterruptedException
public final native void java.lang.Object.wait(long) lance java.lang.InterruptedException
public booléen java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public natif int java.lang.Object.hashCode()
public final natif java.lang.Class java.lang.Object.getClass()
public final natif vide java.lang.Object.notify()
public final natif void java.lang.Object.notifyAll()
1.2.3 Obtenir la méthode spécifiée en fonction du nom de la méthode spécifié et de la liste des paramètres
-
Si la méthode à obtenir est publique, utilisez
getMethod()
la méthode ; -
Si vous souhaitez obtenir des méthodes privées, vous devez utiliser
getDeclaredMethod()
la méthode. -
Comme il existe une méthode portant le même nom, vous devez
getMethod()
spécifier le nom de la méthode à obtenir comme premier paramètre de la méthode, suivi de la liste des paramètres ; -
Lors de l'utilisation d'une méthode sans paramètre, la liste de paramètres peut être omise ou représentée par null ;
-
Étant donné qu'il peut y avoir des situations dans lesquelles la méthode est introuvable, les exceptions doivent être gérées ou levées ici ;
-
Lors de l’utilisation
getMethod()
d’une méthode qui obtient une modification privée, une exception de méthode introuvable sera également levée.
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
try {
//获取带参方法
Method method = student.getMethod("setAge", Integer.class);
System.out.println(method);
//获取无参方法
Method method2 = student.getMethod("getName", null);
System.out.println(method2);
//获取无参方法
Method method3 = student.getMethod("getName");
System.out.println(method3);
}catch (Exception e){
e.printStackTrace();
}
}
}
Résultats de sortie
public void com.reflect.Student.setAge(java.lang.Integer)
public void com.reflect.Student.getName()
public void com.reflect.Student.getName()
2. Obtenez les variables membres
Obtenez toutes les variables membres
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
Field[] declaredFields = student.getDeclaredFields();
for (Field field: declaredFields){
System.out.println(field);
}
}
}
Résultats de sortie
privé java.lang.String com.reflect.Student.name
privé java.lang.Integer com.reflect.Student.age
public java.lang.String com.reflect.Student.className
3. Obtenir d'autres informations sur la classe
3.1. Obtenez le nom de la classe
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
System.out.println(student.getName());
}
}
Il existe en fait plusieurs façons d'obtenir le nom de la classe :
Ou récupérez-le via le nom de la classe,
Ou faites-le passer à travers l'objet,
Ou obtenez le chemin complet de la classe spécifiée.
3.2. Obtenez le nom du package
Vous pouvez obtenir les informations de chemin complet du package où se trouve la classe.
public class Test {
public static void main(String[] args) {
Class<HighSchoolStudent> student = HighSchoolStudent.class;
Package aPackage = student.getPackage();
System.out.println(aPackage);
}
}
3.3. Obtenez la classe parent
public class Test {
public static void main(String[] args) {
Class<HighSchoolStudent> student = HighSchoolStudent.class;
Class<? super HighSchoolStudent> superclass = student.getSuperclass();
System.out.println(superclass);
}
}
Cette méthode ne peut obtenir que la classe parent directe de la classe. Si vous souhaitez obtenir toutes les classes parent, vous pouvez effectuer une boucle après avoir obtenu la classe parent jusqu'à ce que la classe parent soit Object.
public class Test {
public static void main(String[] args) {
Class<ArrayList> arrayListClass = ArrayList.class;
Class superclass = arrayListClass.getSuperclass();
System.out.println(superclass);
while (! "java.lang.Object".equals(superclass.getName())) {
superclass = superclass.getSuperclass();
System.out.println(superclass);
}
}
}
Sortir:
classe java.util.AbstractList
classe java.util.AbstractCollection
classe java.lang.Object
3.4. Obtenez toutes les interfaces implémentées
Cette méthode peut obtenir toutes les interfaces implémentées par cette classe.
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
Class<ArrayList> arrayListClass = ArrayList.class;
Class<?>[] interfaces = arrayListClass.getInterfaces();
for(Class clazz: interfaces){
System.out.println(clazz.getName());
}
}
}
Le résultat est le suivant :
java.util.Liste
java.util.RandomAccess
java.lang.Cloneable
java.io.Sérialisable