Java反射之对JavaBean的内省操作

上一篇我们说了Java反射之数组的反射应用
这篇我们来模拟实现那些javabean的框架(BeanUtils)的基本操作。

[一] 什么是JavaBean

JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,通过set和get方法获取。
一般我们根据这种方法命名规则,通过反射获得某个或者设置某个属性的时候,假如这个属性名为”x",那么,就会处理以下几步:
1、将x变为大写X,判断x后是否还有字母,有则首字母大写
2、在x前加get

[二] 对JavaBean的复杂内省操作

这是一种比较笨重的方式:
Bean类:

package club.leyvan.muzile;

public class Bean {
    private int x = 10;
    private int y = 20;
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    
}

测试类:

    public static void main(String[] args) throws Exception {
        Bean bean = new Bean();
        System.out.println(getProperty(bean, "x"));
        setProperty(bean, "y", 8);
        System.out.println(getProperty(bean,"y"));
    }
    
    /**
     * 根据属性名获得属性方法
     * @param obj
     * @param propertyName
     * @return
     * @throws Exception
     */
    public static Object getProperty(Object obj,String propertyName) throws Exception{
        Object retVal = null;
        //通过内省获得描述对象
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        //通过描述对象获得该类的所有属性描述
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        //迭代所有属性,获得与规则相同的方法。
        for(PropertyDescriptor pd : pds){
            //如果该属性的名称与方法形参一致
            if(pd.getName().equals(propertyName)){
                //则调用该属性的get方法
                Method method = pd.getReadMethod();
                //get方法都是无参数的
                retVal = method.invoke(obj);
            }
        }
        
        return retVal;
    }
    
    /**
     * 根据属性名设置属性的方法
     * @param obj
     * @param propertyName
     * @param value
     * @throws Exception
     */
    public static void setProperty(Object  obj,String propertyName,Object value) throws Exception{
        //通过内省获得描述对象
                BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
                //通过描述对象获得该类的所有属性描述
                PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
                //迭代所有属性,获得与规则相同的方法。
                for(PropertyDescriptor pd : pds){
                    //如果该属性的名称与方法形参一致
                    if(pd.getName().equals(propertyName)){
                        //则调用该属性的set方法
                        Method method = pd.getWriteMethod();
                        //set方法传入参数
                        method.invoke(obj,value);
                    }
                }
    }

结果:

10
8

将原本等于20的y改为了8

[三] 对JavaBean的简单内省操作

上面是一种笨拙的方式,有更为简单的方法:

    public static void main(String[] args) throws Exception {
        Bean bean = new Bean();
        System.out.println(getProperty(bean, "x"));
        setProperty(bean, "y", 39);
        System.out.println(getProperty(bean,"y"));
    }
    
    public static Object getProperty(Object obj,String propertyName) throws Exception{
        Object retVal = null;
        //直接获得属性描述对象
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
        //根据属性,获得get方法
        Method method = pd.getReadMethod();
        //调用方法
        retVal = method.invoke(obj);
        return retVal;
    }
    
    public static void setProperty(Object  obj,String propertyName,Object value) throws Exception{
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
        Method method = pd.getWriteMethod();
        method.invoke(obj, value);
    }

结果:

10
39

本期Java反射就介绍到这,谢谢大家!

猜你喜欢

转载自www.cnblogs.com/leyvan/p/12461721.html