java内省

介绍

内省(Introspector)是java语言为 javabean 类提供的属性、事件处理的API,用于操作javabean类的

内省 与 反射

内省是建立在 反射 基础之上的,操作 javabean 时,内省更加简单

内省常用的API

Introspector

Introspector 是内省的入口,通过它可以得到一个 beanInfo 对象,再通过 beanInfo 可以获取到 PropertyDescriptor (属性描述器)

BeanInfo beanInfo = Introspector.getBeanInfo(Persion.class);

BeanInfo

通过 Introspector 类返回该类型对象

提供以下功能:

  • 返回属性描述符对象(PropertyDescriptor)
  • 方法描述符对象(MethodDescriptor)
  • bean描述符(BeanDescriptor)对象的方法
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

PropertyDescriptor

功能:

  • 用来描述一个属性
  • 返回该属性的 getter 和 setter方法

描述属性:

for(PropertyDescriptor pro : propertyDescriptors) {
      System.out.println(pro.getName());
}

获取 setter 方法:

//写
pro.getWriteMethod();

获取 getter 方法:

//读
pro.getReadMethod();

案例

person类

public class Person implements Serializable {

    private String name;
    private Integer age;
    private String gender;

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

内省获取属性

public class Main {

    public static void main(String[] args) throws IntrospectionException {
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for(PropertyDescriptor pro : propertyDescriptors) {
            // 忽略class
            if("class".equals(pro.getName())){
                continue;
            }
            System.out.println(pro.getName()+
                    "-"+pro.getReadMethod().getName()+
                    "-"+pro.getWriteMethod().getName());
        }
    }
}

执行结果:

age-getAge-setAge
gender-getGender-setGender
name-getName-setName

可以很容易获取到所有属性,以及对应的 getter、setter 方法

注意:内省中的属性名字

名字最好至少以 两个小写字母开头,例如stuName,而不要使用 sName,否则可能会导致检索属性失败;

注意:内省机制检索属性

是根据 getter 和 setter 方法 确认属性名字,而不是根据类里声明的属性名决定;

满足以下条件之一,内省机制就认为 XXX 为一个属性:

  • 只要类中有getXXX方法(getXXX方法没有方法参数,有返回值)
  • 只要类中有setXXX方法(setXXX方法没有返回值,有一个方法参数)
  • 同时有getXXX及setXXX方法

验证:

Person2类:

package com.std;

public class Person2 implements Serializable{
    // 只有属性,没有setter、getter方法
    private int height;
    // 没有gender属性,只有setter方法
    public void setGender(String gender) {

    }
    // 没有name属性,只有getter方法
    public String getName() {
        return "李雷";
    }

    // 没有age属性,有getter、setter方法
    public Integer getAge() {
        return 123;
    }

    public void setAge(Integer age) {

    }
}

获取javabean的属性:

public class Main2 {

    public static void main(String[] args) throws IntrospectionException {
        BeanInfo beanInfo = Introspector.getBeanInfo(Person2.class);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for(PropertyDescriptor pro : propertyDescriptors) {
            if("class".equals(pro.getName())){
                continue;
            }
            Method getter = pro.getReadMethod();
            Method setter = pro.getWriteMethod();

            String content = pro.getName()+"-";
            if(getter != null){
                content += getter.getName()+"-";
            }
            if(setter != null){
                content += setter.getName();
            }
            System.out.println(content);
        }
    }
}

执行结果:

age-getAge-setAge
gender-setGender
name-getName-

没有 height 属性,说明内省中的属性,是根据 setter、getter 方法获取的


原文出处:/show_1IX3wjlAtwVS.html