Home  >  Article  >  Java  >  How to implement Java introspection mechanism

How to implement Java introspection mechanism

WBOY
WBOYforward
2023-04-24 08:04:061479browse

    Concept

    JavaBean

    In actual programming, we often need some classes to wrap value objects, such as Student, Employee , Order, there are often no business methods in these classes, they are just to encapsulate the entity objects that need to be processed. They have the following characteristics:

    • The properties are all private;

    • There is a public constructor without parameters;

    • Provide public getXxx methods and setXxx methods for private properties as needed;

    For example: if the attribute name is name, then the getName method returns the attribute name value, and the setName method sets the name value; note that the name of the method is usually get or set plus the attribute name, and the first letter of the attribute name is capitalized; these methods Called getters/setters; getters must have return values ​​and no method parameters; setter values ​​have no return values ​​and have method parameters;

    For example, the following example:

    How to implement Java introspection mechanism

    Classes that meet these characteristics are called JavaBeans;

    Introspection

    The introspection (Inspector) mechanism is based on reflection. The Java language has a lack of Bean class attributes and events. Save processing methods.

    As long as there is a getXXX method, or setXXX method, or both getXXX and setXXX methods in the class, the getXXX method has no method parameters and has a return value; the setXXX method has no return value and has a method parameter; then introspection The mechanism considers XXX to be an attribute;

    For example, in the code below

    the age attribute is not declared at all in the Employee class, only such getters and setters are declared. The introspection mechanism considers age to be an attribute

    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) {
            
    
        }
    }

    Related API

    The main classes and interfaces related to Java introspection are:

    • java.beans.Introspector class: Provides standard methods for obtaining JavaBean properties, events, and methods; usually use the getBeanInfo method to return the BeanInfo object;

    • ##Java.beans.BeanInfo interface: It cannot be instantiated directly. This type of object is usually returned through the Introspector class, which provides methods for returning property descriptor objects (PropertyDescriptor), method descriptor objects (MethodDescriptor), and bean descriptor (BeanDescriptor) objects;

    • Java.beans.PropertyDescriptor class: Used to describe a property, which has getter and setter methods;

    You can use the methods of the PropertyDescriptor class Obtain property-related information, for example, the getName method returns the name of the property:

    The PropertyDescriptor class defines methods that can obtain the getter and setter methods of the property

    MethodMethod descriptionMethod getReadMethod()Returns the getter method object corresponding to the attribute;Method getWriteMethod()Returns the setter method object corresponding to the attribute;
    Let’s use the code to explore in depth:

    Code Case: Obtain attribute-related information

    Employee As shown in the above code, continue to write the main function for testing

    First use the BeanInfo interface to obtain the BeanInfo object, and then obtain the PropertyDescriptor attribute description through the BeanInfo object

     //获取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());
    }

    The running results are as follows:

    How to implement Java introspection mechanism

    We can also call the get or set method obtained here through reflection

    //创建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());

    The running results are as follows:

    How to implement Java introspection mechanism

    All codes are attached at the bottom! ! ! ! ! !

    Notes on introspection properties

    • Many frameworks use the introspection mechanism to retrieve the properties of objects. When defining property names, the names are the most It is best to at least start with two lowercase letters, such as stuName, instead of using sName. In some cases, it may cause the attribute retrieval to fail;

    • When the introspection mechanism retrieves attributes, it is based on The getter and setter methods confirm the property name instead of determining it based on the member variable name declared in the class;

    Full code

    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='" + name + '\'' +
                    ", score=" + score +
                    '}';
        }
    
        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());
        }
    }

    The above is the detailed content of How to implement Java introspection mechanism. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete