• BeanUtils


    BeanUtils工具包是由Apache公司所开发,主要是方便程序员对Bean类能够进行简便的操作。

    在这里,不讲解如何使用apache的BeanUtils工具,而是我们自己写底层,自己利用类反射来实现BeanUtils的功能。 
    需要先学习类反射!

    通过给定bean对象的类,和封装的Map对象,返回出一个bean对象。

    准备bean对象:

    这里准备了User类和Book类:

    User

    package cn.hncu.domain;
    
    /**
     * @author 陈浩翔
     *
     * 2016-8-25
     */
    public class User {
        private String uuid;
        private String name;
        private int age;
        public String getUuid() {
            return uuid;
        }
        public void setUuid(String uuid) {
            this.uuid = uuid;
        }
        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 int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            User other = (User) obj;
            if (uuid == null) {
                if (other.uuid != null)
                    return false;
            } else if (!uuid.equals(other.uuid))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return "User [uuid=" + uuid + ", name=" + name + ", age=" + age + "]";
        }
    
    }
    

    Book

    package cn.hncu.domain;
    
    /**
     * @author 陈浩翔
     *
     * 2016-8-25
     */
    public class Book {
        private String uuid;
        private String name;
        private double inPrice;
        private double outPrice;
        private int num;
        public String getUuid() {
            return uuid;
        }
        public void setUuid(String uuid) {
            this.uuid = uuid;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public double getInPrice() {
            return inPrice;
        }
        public void setInPrice(double inPrice) {
            this.inPrice = inPrice;
        }
        public double getOutPrice() {
            return outPrice;
        }
        public void setOutPrice(double outPrice) {
            this.outPrice = outPrice;
        }
        public int getNum() {
            return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Book other = (Book) obj;
            if (uuid == null) {
                if (other.uuid != null)
                    return false;
            } else if (!uuid.equals(other.uuid))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return "Book [uuid=" + uuid + ", name=" + name + ", inPrice=" + inPrice
                    + ", outPrice=" + outPrice + ", num=" + num + "]";
        }
    }
    

    过度版的:

    先看过度版的:接参后需要强转成对应的bean,因为返回类型是Object。

    MyBeanUtils1

    package cn.hncu.beanUtils;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Map;
    
    public class MyBeanUtils1 {
    
        public static Object populate(Class cls ,Map map) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
            Object obj = null;
    
            //1、用类反射new出对象
            obj = cls.newInstance();
    
            //2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置
            //2.1遍历出所有该类声明的属性
            Field flds[] = cls.getDeclaredFields();//getDeclaredFields()返回Class中所有的字段,包括私有字段;
            for(Field fld:flds){
                //获取该fld对象所代表的属性名
                String fldName = fld.getName();
                //根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值 
                Object value = map.get(fldName);
                if(value==null){//如果map中不存在对应的属性数据,我们在这里给出提示信息
                    System.out.println(fldName+"的数据为空");
                }else{
                    //如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字
                    String mothodName = "set"+fldName.substring(0, 1).toUpperCase()+fldName.substring(1);
    
                     //根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象
                    Class paramTypes[] = new Class[1];
                    paramTypes[0] = fld.getType();
                    Method method = cls.getDeclaredMethod(mothodName, paramTypes);
    
                    //调用该method对象所代表的方法
                    Object args[] = new Object[1];
                    args[0]=value;
                    method.invoke(obj, args);
                }
            }
            return obj;
        }
    
    }

    测试

    @Test
        public void test1() {
            Map map = new HashMap();
            map.put("uuid", "001");
            map.put("name", "Jack");
            map.put("age", 20);
    
            Map map2 = new HashMap();
            map2.put("uuid", "001");
            map2.put("name", "红楼梦");
            map2.put("inPrice", 20.5);
            //数据可能不全
            map2.put("num", 123);
            try {
                User user =  (User) MyBeanUtils1.populate(User.class, map);
                System.out.println(user);
                Book book =  (Book) MyBeanUtils1.populate(Book.class, map2);
                System.out.println(book);
            } catch (ReflectiveOperationException e) {
                e.printStackTrace();
            }
        }

    测试结果:

    这个还不是很完善,为什么呢,因为返回类型是Object,每次都要强转,比较麻烦,而且我们传了bean的class对象过去了,完全可以实现不用强转的,这个时候我们就需要用到泛型了。 
    而且Map的泛型我们可以确定了,肯定是Map<String,Object>这样的

    好了,学习一下最终版的、

    最终版:

    MyBeanUtils

    package cn.hncu.beanUtils;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Map;
    
    public class MyBeanUtils {
    
        public static<T> T populate(Class<T> cls ,Map<String, Object> map) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
            T obj = null;
    
            //1、用类反射new出对象
            obj = cls.newInstance();
    
            //2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置
            //2.1遍历出所有该类声明的属性
            Field flds[] = cls.getDeclaredFields();//getDeclaredFields()返回Class中所有的字段,包括私有字段;
            for(Field fld:flds){
                //获取该fld对象所代表的属性名
                String fldName = fld.getName();
                //根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值 
                Object value = map.get(fldName);
                if(value==null){//如果map中不存在对应的属性数据,我们在这里给出提示信息
                    System.out.println(fldName+"的数据为空");
                }else{
                    //如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字
                    String mothodName = "set"+fldName.substring(0, 1).toUpperCase()+fldName.substring(1);
    
                     //根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象
                    Class<?> paramTypes[] = new Class[1];
                    paramTypes[0] = fld.getType();
                    Method method = cls.getDeclaredMethod(mothodName, paramTypes);
    
                    //调用该method对象所代表的方法
                    Object args[] = new Object[1];
                    args[0]=value;
                    method.invoke(obj, args);
                }
            }
            return obj;
        }
    
    }
    

    测试方法:

    @Test
        @SuppressWarnings("unchecked")
        public void test() {
            Map<String, Object> map = new HashMap();
            map.put("uuid", "001");
            map.put("name", "Jack");
            map.put("age", 20);
    
            Map<String, Object> map2 = new HashMap();
            map2.put("uuid", "001");
            map2.put("name", "红楼梦");
            map2.put("inPrice", 20.5);
            //数据可能不全
            map2.put("num", 123);
            try {
                User user = MyBeanUtils.populate(User.class, map);
                System.out.println(user);
                Book book = MyBeanUtils.populate(Book.class, map2);
                System.out.println(book);
            } catch (ReflectiveOperationException e) {
                e.printStackTrace();
            }
        }

    测试结果:

    完整项目源码链接:

    –>点击访问本系列源码–

    转载请注明出处:http://blog.csdn.net/qq_26525215

  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/tengqiuyu/p/7489384.html
Copyright © 2020-2023  润新知