Maison  >  Article  >  Java  >  Comment implémenter le mécanisme d'introspection Java

Comment implémenter le mécanisme d'introspection Java

WBOY
WBOYavant
2023-04-24 08:04:061589parcourir

    Concept

    JavaBean

    Dans la programmation réelle, nous avons souvent besoin de certaines classes utilisées pour envelopper des objets de valeur, tels que Student, Employee et Order. Ces classes n'ont souvent pas de méthodes métier, juste pour stocker le. les entités qui doivent être traitées sont encapsulées et ont les caractéristiques suivantes :

    • les attributs sont tous privés ;

    • a une méthode de constructeur publique sans paramètres

    • fournit des méthodes publiques getXxx et setXxx selon les besoins ; pour les attributs privés ;

    Par exemple : si le nom de l'attribut est name, alors la méthode getName renvoie la valeur du nom de l'attribut et la méthode setName définit la valeur du nom. Notez que le nom de la méthode est généralement get ou set plus ; le nom de l'attribut, et la première lettre du nom de l'attribut est en majuscule ; ces méthodes appelées getters/setters doivent avoir des valeurs de retour et aucune valeur de setter n'a de valeurs de retour et n'a pas de paramètres de méthode ;

    Par exemple, l'exemple suivant :

    Comment implémenter le mécanisme dintrospection Java

    Les classes qui répondent à ces caractéristiques sont appelées JavaBeans ;

    Introspection

    Le mécanisme d'introspection (Inspector) est basé sur la réflexion et est une méthode de traitement par défaut du langage Java pour la classe Bean. propriétés et événements.

    Tant qu'il y a une méthode getXXX, ou une méthode setXXX, ou les deux méthodes getXXX et setXXX dans la classe, la méthode getXXX n'a ​​pas de paramètres de méthode et a une valeur de retour ; ; alors le mécanisme d'introspection considérera que XXX est un attribut ;

    Par exemple, dans le code suivant

    l'attribut age n'est pas du tout déclaré dans la classe Employee, seuls ces getters et setters sont déclarés. être un attribut

    package com.shixun.introspector;
    
    public class Employee {
        private String name;
        private Double score;
    
        // age将被内省认为是属性
        public int getAge(){
            return 30;
        }
    
        // name将被内省认为是属性
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // score将被内省认为是属性
        public Double getScore() {
            return score;
        }
    
        public void setScore(Double score) {
            this.score = score;
        }
    
        public static void main(String[] args) {
            
    
        }
    }

    API associée

    Liée à l'introspection Java Les principales classes et interfaces sont :

    • classe java.beans.Introspector : fournit des méthodes standard pour obtenir les propriétés, les événements et les événements JavaBean. méthodes ; utilisent généralement la méthode getBeanInfo pour renvoyer l'objet BeanInfo ;

      java.beans.Introspector类: 为获得JavaBean属性、事件、方法提供了标准方法;通常使用其中的getBeanInfo方法返回BeanInfo对象;

    • Java.beans.BeanInfo接口:不能直接实例化,通常通过Introspector类返回该类型对象,提供了返回属性描述符对象(PropertyDescriptor)、方法描述符对象(MethodDescriptor) 、 bean描述符(BeanDescriptor)对象的方法;

    • Java.beans.PropertyDescriptor类

    • Interface Java.beans.BeanInfo : ce type d'objet est généralement renvoyé via la classe Introspector qu'il fournit. l'objet descripteur de propriété de retour (PropertyDescriptor), l'objet descripteur de méthode (MethodDescriptor), le bean Méthodes de l'objet descripteur (BeanDescriptor)

    Classe Java.beans.PropertyDescriptor : utilisée pour décrire une propriété, qui a des méthodes getter et setter ;

    Vous pouvez utiliser la classe PropertyDescriptor Methods pour obtenir des informations relatives à la propriété, par exemple, la méthode getName renvoie le nom de la propriété : La classe PropertyDescriptor définit des méthodes qui peuvent obtenir le getter et méthodes setter de la propriété
    method Description de la méthode
    Method getReadMethod() Renvoie l'objet méthode getter correspondant à l'attribut ;
    Method getWriteMethod()

    Return est l'objet méthode setter correspondant à l'attribut ;

    Utilisons le code pour explorer en profondeur :

    Cas de code : obtenir les informations relatives à l'attribut

    Employé Comme indiqué dans le code ci-dessus, continuez à écrire la fonction principale pour les testsComment implémenter le mécanisme dintrospection Java

    Première utilisation l'interface BeanInfo pour obtenir l'objet BeanInfo, puis obtenir la description de l'attribut PropertyDescriptor via l'objet BeanInfo

     //获取BeanInfo的对象
     BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class);
     //通过BeanInfo对象获取PropertyDescriptor属性描述
     PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors();
     System.out.println("通过Inspector内省机制获取JavaBean属性======= 打印所有信息 ====================");
     Arrays.stream(propertyDescriptors).forEach(f->{
         System.out.println("====================================");
         System.out.println("属性名:"+f.getName());
         System.out.println("类型:"+f.getPropertyType());
         System.out.println("get方法:"+f.getReadMethod());
         System.out.println("set方法:"+f.getWriteMethod());
     });
    
    // 或者用增强for
    System.out.println("通过Inspector内省机制获取JavaBean属性======= 打印所有信息 ====================");
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
    	System.out.println("====================================");
        System.out.println("名字:" + propertyDescriptor.getName());
        System.out.println("类型:" + propertyDescriptor.getPropertyType());
        System.out.println("get方法:" + propertyDescriptor.getReadMethod());
        System.out.println("set方法:" + propertyDescriptor.getWriteMethod());
    }

    Les résultats d'exécution sont les suivants :

    Comment implémenter le mécanisme dintrospection Java

    Nous pouvons également La méthode get ou set obtenue ici est appelée par réflexion
    //创建Employee的对象
    Class<?> clazz = Class.forName("com.shixun.introspector.Employee");
    Object employee = clazz.newInstance();
    
    //遍历属性描述对象
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
        //打印属性名称
        System.out.println(propertyDescriptor.getName());
        //判断属性名称是不是name
        if (propertyDescriptor.getName().equals("name")) {
            //setter方法
            Method writeMethod = propertyDescriptor.getWriteMethod();
            //调用setName方法
            writeMethod.invoke(employee, "jack");
            //getter方法
            Method readMethod = propertyDescriptor.getReadMethod();
            //调用getName方法
            Object nameValue = readMethod.invoke(employee);
            System.out.println("name属性的值为:" + nameValue);
        }
        //判断属性名称是否为score
        if (propertyDescriptor.getName().equals("score")) {
            //setter方法
            Method scoreWriteMethod = propertyDescriptor.getWriteMethod();
            //调用setScore方法
            scoreWriteMethod.invoke(employee, new Double(3000));
            //getter方法
            Method scoreReadMethod = propertyDescriptor.getReadMethod();
            Object scoreValue = scoreReadMethod.invoke(employee);
            System.out.println("score属性的值为:" + scoreValue);
        }
    }
    System.out.println("当前对象的信息:"+employee.toString());

    Le résultat en cours d'exécution est le suivant :

      Tous les codes sont attachés en bas ! ! ! ! ! !
    • Notes sur les attributs d'introspection
    • De nombreux frameworks utilisent le mécanisme d'introspection pour récupérer les attributs des objets, lors de la définition des noms d'attribut, il est préférable de commencer le nom par au moins deux lettres minuscules, telles que stuName, plutôt que. en utilisant sName , dans certains cas, cela peut entraîner l'échec de la récupération des attributs ;

    🎜Lorsque le mécanisme d'introspection récupère les attributs, il confirme le nom de l'attribut en fonction des méthodes getter et setter, plutôt qu'en fonction du nom de la variable membre déclaré dans la classe 🎜🎜🎜🎜 Code complet 🎜
    package com.shixun.introspector;
    
    import java.beans.BeanInfo;
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class Employee {
        private String name;
        private Double score;
    
        // age将被内省认为是属性
        public int getAge() {
            return 30;
        }
    
        // name将被内省认为是属性
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // score将被内省认为是属性
        public Double getScore() {
            return score;
        }
    
        public void setScore(Double score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "name=&#39;" + name + &#39;\&#39;&#39; +
                    ", score=" + score +
                    &#39;}&#39;;
        }
    
        public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
            //获取BeanInfo的对象
            BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class);
    
            //通过BeanInfo对象获取PropertyDescriptor属性描述
            PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors();
    //        System.out.println("通过Inspector内省机制获取JavaBean属性======= 打印所有信息 ====================");
    //        Arrays.stream(propertyDescriptors).forEach(f->{
    //            System.out.println("====================================");
    //            System.out.println("属性名:"+f.getName());
    //            System.out.println("类型:"+f.getPropertyType());
    //            System.out.println("get方法:"+f.getReadMethod());
    //            System.out.println("set方法:"+f.getWriteMethod());
    //        });
    //
    //
    //
    //        System.out.println("通过Inspector内省机制获取JavaBean属性======= 打印所有信息 ====================");
    //
    //        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
    //            System.out.println("名字:" + propertyDescriptor.getName());
    //            System.out.println("类型:" + propertyDescriptor.getPropertyType());
    //            System.out.println("get方法:" + propertyDescriptor.getReadMethod());
    //            System.out.println("set方法:" + propertyDescriptor.getWriteMethod());
    //        }
    
            //创建Employee的对象
            Class<?> clazz = Class.forName("com.shixun.introspector.Employee");
            Object employee = clazz.newInstance();
    
            //遍历属性描述对象
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                //打印属性名称
                System.out.println(propertyDescriptor.getName());
                //判断属性名称是不是name
                if (propertyDescriptor.getName().equals("name")) {
                    //setter方法
                    Method writeMethod = propertyDescriptor.getWriteMethod();
                    //调用setName方法
                    writeMethod.invoke(employee, "jack");
                    //getter方法
                    Method readMethod = propertyDescriptor.getReadMethod();
                    //调用getName方法
                    Object nameValue = readMethod.invoke(employee);
                    System.out.println("name属性的值为:" + nameValue);
                }
                //判断属性名称是否为score
                if (propertyDescriptor.getName().equals("score")) {
                    //setter方法
                    Method scoreWriteMethod = propertyDescriptor.getWriteMethod();
                    //调用setScore方法
                    scoreWriteMethod.invoke(employee, new Double(3000));
                    //getter方法
                    Method scoreReadMethod = propertyDescriptor.getReadMethod();
                    Object scoreValue = scoreReadMethod.invoke(employee);
                    System.out.println("score属性的值为:" + scoreValue);
                }
            }
    
            System.out.println("当前对象的信息:"+employee.toString());
        }
    }

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer