Lorsque le programme est en cours d'exécution, la structure du programme ou le type de variable peut changer. Ce langage est appelé langage dynamique. Nous pensons que Java n'est pas un langage dynamique, mais il possède un mécanisme dynamique très important, communément appelé : la réflexion.
On dit dans l'industrie informatique que sans réflexion il n'y aurait pas de cadre. Les cadres existants sont tous basés sur la réflexion. Dans le développement de projets réels, les frameworks sont les plus utilisés et les classes sont le plus remplies. Le concept de réflexion est le médiateur qui combine les frameworks et les classes. La réflexion est donc le tremplin pour contacter le développement de projets !
Qu'est-ce que le mécanisme de réflexion
Le mécanisme de réflexion est en cours d'exécution Pour n'importe quelle classe, il peut connaître tous les attributs et. attributs de cette classe. Méthode ; pour n'importe quel objet, n'importe laquelle de ses méthodes et propriétés peut être appelée ; ces informations obtenues dynamiquement et la fonction d'appel dynamique des méthodes de l'objet sont appelées le mécanisme de réflexion du langage Java.
Ce que peut faire le mécanisme de réflexion
Le mécanisme de réflexion assure principalement les fonctions suivantes :
Déterminer la classe à laquelle appartient tout objet au moment de l'exécution
Construire un objet de n'importe quelle classe au moment de l'exécution
Implémentation de fonctions spécifiques
1 Il existe trois façons d'obtenir la classe via le mécanisme de réflexion. Obtenons le type Employé.
//第一种方式: Classc1 = Class.forName("Employee"); //第二种方式: //java中每个类型都有class 属性. Classc2 = Employee.class; //第三种方式: //java语言中任何一个java对象都有getClass 方法 Employeee = new Employee(); Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
Class c =Class.forName("Employee"); //创建此Class 对象所表示的类的一个新实例 Objecto = c.newInstance(); //调用了Employee的无参数构造方法.
//获取整个类 Class c = Class.forName("java.lang.Integer"); //获取所有的属性? Field[] fs = c.getDeclaredFields(); //定义可变长的字符串,用来存储属性 StringBuffer sb = new StringBuffer(); //通过追加的方法,将每个属性拼接到此字符串中 //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n"); //里边的每一个属性 for(Field field:fs){ sb.append("\t");//空格 sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb);
public static void main(String[] args) throws Exception{ <span style="white-space:pre"> </span>//以前的方式: /* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //获取类 Class c = Class.forName("User"); //获取id属性 Field idF = c.getDeclaredField("id"); //实例化这个类赋给o Object o = c.newInstance(); //打破封装 idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。 //给o对象的id属性赋值"110" idF.set(o, "110"); //set //get System.out.println(idF.get(o)); }
Réflexion sur la méthode
La classe Class a la méthode la plus simple, getName() :public class Demo2 { public static void main(String[] args) { Class c1 = int.class;//int 的类类型 Class c2 = String.class;//String类的类类型 Class c3 = void.class; System.out.println(c1.getName()); System.out.println(c2.getName()); System.out.println(c2.getSimpleName()); System.out.println(c3.getName()); } }
public class ClassUtil { public static void printClassMethodMessage(Object obj){ //要获取类的信息》》首先我们要获取类的类类型 Class c = obj.getClass(); //我们知道Object类是一切类的父类,所以我们传递的是哪个子类的对象,c就是该子类的类类型。 //接下来我们要获取类的名称System.out.println("类的名称是:"+c.getName()); /* *我们知道,万事万物都是对象,方法也是对象,是谁的对象呢? * 在java里面,方法是Method类的对象 *一个成员方法就是一个Method的对象,那么Method就封装了对这个成员 *方法的操作 *///如果我们要获得所有的方法,可以用getMethods()方法,这个方法获取的是所有的Public的函数,包括父类继承而来的。如果我们要获取所有该类自己声明的方法,就可以用getDeclaredMethods()方法,这个方法是不问访问权限的。 Method[] ms = c.getMethods();//c.getDeclaredMethods() //接下来我们拿到这些方法之后干什么?我们就可以获取这些方法的信息,比如方法的名字。 //首先我们要循环遍历这些方法 for(int i = 0; i < ms.length;i++){ //然后可以得到方法的返回值类型的类类型 Class returnType = ms[i].getReturnType(); //得到方法的返回值类型的名字 System.out.print(returnType.getName()+" "); //得到方法的名称 System.out.print(ms[i].getName()+"("); //获取参数类型--->得到的是参数列表的类型的类类型 Class[] paramTypes = ms[i].getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } } }
Obtenez le nom de la classe grâce à la réflexion de la méthode Étapes :
Obtenez le type de classe de la classe
. 2. Obtenez la méthode de la classe via le type de classe (getMethods())
3. Parcourez les méthodes obtenues
4 Obtenez le type de classe du type de valeur de retour via getReturnType() de ces méthodes, et. puis récupérez le type de classe via le type de classe. Le nom du type de valeur de retour
5.getName() obtient le nom de la méthode et getParameterTypes() obtient le type de classe du type de paramètre dans cette méthode.
Réflexion des variables membres
public class ClassUtil { public static void printFieldMessage(Object obj){ Class c = obj.getClass(); //Field[] fs = c.getFields(); }
Field[] fs = c.getDeclaredFields();
for (Field field : fs) { //得到成员变量的类型的类类型 Class fieldType = field.getType(); String typeName = fieldType.getName(); //得到成员变量的名称 String fieldName = field.getName(); System.out.println(typeName+" "+fieldName); }
Réflexion du constructeur
Qu'il s'agisse d'une réflexion de méthode, d'une réflexion de variable membre ou d'une réflexion de constructeur, nous tout ce que vous devez savoir est : si vous souhaitez obtenir des informations sur une classe, vous devez d'abord obtenir le type de classe de la classe.public static void printConMessage(Object obj){Class c = obj.getClass(); /* * 首先构造函数也是对象,是java.lang.Constructor类的对象 * 也就是java.lang. Constructor中封装了构造函数的信息 * 和前面说到的一样,它也有两个方法: * getConstructors()方法获取所有的public的构造函数 * getDeclaredConstructors()方法得到所有的自己声明的构造函数 */ //Constructor[] cs = c.getConstructors(); Constructor[] cs = c.getDeclaredConstructors(); for (Constructor constructor : cs) { //我们知道构造方法是没有返回值类型的,但是我们可以: System.out.print(constructor.getName()+"("); //获取构造函数的参数列表》》得到的是参数列表的类类型 Class[] paramTypes = constructor.getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } }