Map与JavaBean互转原理(内省机制)

1.javabean 转 map

  • 定义一个Person的javabean
        public class Person {

        private String name;
        private int age;

        public Person() {
            super();
        }

        public Person(String name,int age){
            this.name=name;
            this.age=age;
        }

        public String getName() {
            return name;
        }

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

        public int getAge() {
            return age;
        }

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

        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }



    }

解说:

定义一个Person的javabean是用来下面演示demo使用
  • 将map集合转javabean
        /**
         * javabean转成map
         * @param obj
         * @return
         * @throws Exception
         */
        public static Map<String,Object> bean2Map(Object obj) throws Exception{
            Map<String, Object> map =new HashMap<>();
            // 获取person类的BeanInfo对象
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            //获取属性描述器
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

                //获取属性名
                String key = propertyDescriptor.getName();
                if(key.equals("class"))
                    continue;
                //获取该属性的值
                Method readMethod = propertyDescriptor.getReadMethod();
                通过反射来调用Person的定义的getName()方法
                Object value = readMethod.invoke(obj);
                map.put(key, value);
            }
            return map;
        }

        /**
         * 打印map集合
         * @param map
         */
        private static void printMap(Map<String, Object> map) {
            for (Entry<String, Object> m : map.entrySet()) {
                System.out.println(m.getKey()+"="+m.getValue());
            }
            System.out.println("---------------------------------");
        }

        -------------------------------
        执行main方法:
        public static void main(String[] args) throws Exception {
            Person per=new Person("liujun",12);
            Map<String, Object> bean2Map = bean2Map(per);
            printMap(bean2Map);
        }

        ----------------------
        输出的结果:
        name=liujun
        age=12
        ---------------------------------

解说:

1.Introspector 类:获取person类的BeanInfo对象

2.BeanInfo 类:person类的BeanInfo对象

3.PropertyDescriptor 类:person类的属性描述器

2.map 转 javabean

    /**
     * map集合转javabean
     * @param map
     * @param clz
     * @return
     * @throws Exception
     */

    public static <T>T map2Bean(Map<String,Object> map , Class<T> clz) throws Exception{
        //new 出一个对象
        T obj=clz.newInstance();
        // 获取person类的BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(clz);
        //获取属性描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            //获取属性名
            String key = propertyDescriptor.getName();
            Object value=map.get(key);
            if(key.equals("class"))
                continue;
            Method writeMethod = propertyDescriptor.getWriteMethod();
            //通过反射来调用Person的定义的setName()方法
            writeMethod.invoke(obj,value);
        }
        return obj;
    }

    -------------------------------
    执行main方法:
    public static void main(String[] args) throws Exception {
        Person per=new Person("liujun",12);
        Map<String, Object> bean2Map = bean2Map(per);
        printMap(bean2Map);
        Person map2Bean = map2Bean(bean2Map, Person.class);
        System.out.println(map2Bean.toString());
    }

    -----------------------------
    输出的结果:
    name=liujun
    age=12
    ---------------------------------
    Person [name=liujun, age=12]

3.转换的原理(内省机制)

  • 什么是内省机制?

    内省机制是获取JavaBean的成员(事件,方法,属性),设置/获取属性值

  • 内省机制与反射有什么区别?

    反射是获取类的字节码对象,通过字节码对象创建类的对象,调用相关方法

  • 内省机制的核心类:

    Introspector

    Introspector类为访问目标Jave Bean支持的属性、事件和方法提供了标准方法。对于属性、事件和方法中的每一类信息,Introspector会分别分析目标bean以及其父类,寻找显式或隐式信息并用其构建一个能够全面描述目标bean的BeanInfo对象。过调用Introspector.getBeanInfo()方法来获得指定类的bean信息
    

    BeanInfo

    BeanInfo类是为了获取对bean属性的控制权。只需提供属性名和所属的bean类,就可以为每个属性构建一个PropertyDescriptor
    

    PropertyDescriptor

    PropertyDescriptor是属性描述器,通过PropertyDescriptor可以获取javabean中的定义的属性、事件和方法。
    
  • 内省机制代码的分析:

        public static void main(String[] args) throws Exception {
            //通过Introspector获取person类的BeanInfo对象
            BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
            //通过beanInfo对象获取属性描述器propertyDescriptors
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            //遍历每一个属性描述器PropertyDescriptors     
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                System.out.println("-------------");
                //获取某个属性的名称:例如:Person的定义的name属性名
                System.out.println(propertyDescriptor.getName());
                //获取某个属性的类型:例如:Person的定义的name属性的类型是class java.lang.String
                System.out.println(propertyDescriptor.getPropertyType());
                //获取某个属性的getxxx()方法,例如:Person的定义的getName()方法
                Method readMethod = propertyDescriptor.getReadMethod();
                //获取某个属性的setxxx()方法,例如:Person的定义的setName()方法
                Method writeMethod = propertyDescriptor.getWriteMethod();
                System.out.println(readMethod);
                System.out.println(writeMethod);
            }
        }

        -------------------------------

        输出的结果:

        -------------
        age
        int
        public int xmg.day24.neisheng.Person.getAge()
        public void xmg.day24.neisheng.Person.setAge(int)
        -------------
        class
        class java.lang.Class
        public final native java.lang.Class java.lang.Object.getClass()
        null
        -------------
        name
        class java.lang.String
        public java.lang.String xmg.day24.neisheng.Person.getName()
        public void xmg.day24.neisheng.Person.setName(java.lang.String)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值