Maison > Java > javaDidacticiel > le corps du texte

Mécanisme de réflexion Java

伊谢尔伦
Libérer: 2017-01-16 11:58:12
original
1522 Les gens l'ont consulté

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

  • Juger les variables membres et les méthodes de n'importe quelle classe au moment de l'exécution

  • Appeler la méthode de n'importe quel objet au moment de l'exécution

  • Générer proxy dynamique.

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)
Copier après la connexion
2. Créer un objet : Après avoir obtenu la classe, nous créons son objet, en utilisant newInstance :

Class c =Class.forName("Employee");  
  
//创建此Class 对象所表示的类的一个新实例  
Objecto = c.newInstance(); //调用了Employee的无参数构造方法.
Copier après la connexion
3. Récupérez les attributs : divisés en tous les attributs et attributs spécifiés :

Regardez d'abord comment obtenir tous les attributs :

//获取整个类  
            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);
Copier après la connexion
Obtenez des attributs spécifiques et apprenez en comparant avec les méthodes traditionnelles :

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));  
}
Copier après la connexion

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());
}
}
Copier après la connexion
La méthode getName peut imprimer le nom de classe du type de classe. utiliser la méthode getSimpleName() peut imprimer le nom de la classe sans le nom du package. Comme le montre le code ci-dessus, les types de données de base et les mots-clés vides existent tous dans les types de classe.

Cas :

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(")");
}
}
}
Copier après la connexion
Idée récapitulative :

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

Nous devons d'abord réaliser que les variables membres sont également des objets et sont java.lang .reflect Objet de classe .Field, c'est-à-dire que la classe Field encapsule les opérations sur les variables membres. Puisqu'il encapsule les variables membres, comment obtenons-nous ces variables membres ? Il a une telle méthode :

public class ClassUtil {
public static void printFieldMessage(Object obj){
Class c = obj.getClass();
//Field[] fs = c.getFields();
}
Copier après la connexion
La méthode getFields() obtient ici les informations de toutes les variables membres publiques. Et les variables membres publiques dans la méthode de réflexion contiennent également des informations sur toutes les variables membres auto-déclarées :


Field[] fs = c.getDeclaredFields();
Copier après la connexion
Après l'avoir obtenue, nous pouvons parcourir (puisque les informations du champ sont encapsulées, alors nous peut obtenir le type de champ)

for (Field field : fs) {
//得到成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}
Copier après la connexion

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(")");
}
}
Copier après la connexion


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal