利用反射机制实现对象转Map集合

更多关于Java方面的文章,欢迎访问燕归来https://www.zhoutao123.com

前不久有个需求,实现对象转换为map,这里思考了一些,没有用别人的轮子,自己实现了这个需求,写了一个简单的工具类来做这个。

分析问题

问题主要有以下几点

  • 如何获取对象中的属性的名称?
  • 如何获取对象的属性值?如何这个属性被private修饰,该如何处理?
  • 返回的是一个对象该如何获取对象的属性参数呢?

解决问题

  • 问题1:可以使用反射来获取POJO对象的get方法(当然包括boolean类型的is方法),然后来处理成为属性,主要逻辑是分析是否包以is或者get关键字开头,如果是的话那么返回处理后的数据信息。转换简略代码如下:
 /**
     * 处理方法,将get方法转换为属性名
     *
     * @param methodName
     * @return
     */
    public static String dealMethodName(String methodName) {
        StringBuilder stringBuilder = new StringBuilder();
        if (methodName.startsWith("get")) {
            stringBuilder.append(methodName.toLowerCase().charAt(3)).append(methodName.substring(4));
        } else if (methodName.startsWith("is")) {
            stringBuilder.append(methodName.toLowerCase().charAt(2)).append(methodName.substring(3));
        } else {
            return methodName;
        }
        return stringBuilder.toString();
    }
  • 问题2:由于可以获取到POJO对象的get方法,因此我们可执行这个方法来进行获取到结果,从而也避免了private修饰的问题。

  • 问题3:如果使用get方法获取过来的是一个对象,那么我们可以通过判断是不是Object类来判断是不是需要迭代处理,后来发现,在使用一些基础数据类的时候,比如int,char,float等,他会自定的装箱,从而导致我们无法处理,后来取了一个折中的办法自定义了一个注解,在返回值是POJO对象的地方标注,在使用反射获取get方法中获取这个注解,如果注解是null说明不是POJO,如果不是null,那么我们进行二次的迭代处理该对象,注解代码如下:

//作用于方法上,运行时保留
@Target(value={METHOD})
@Retention(RetentionPolicy.RUNTIME)
public  @interface NeedIterative {
    //参数没有作用
    String value() default "";
}

详细代码

首先实现POJO类,POJO类主要代码如下所示<span style="color:red;">set方法已省略,自行补充,People类也是</span>,

public class Student{
    private String name;
    private int age;
    private float height;
    private double weight;
    private char sex;
    private boolean allow;
    private People people;

    public Student(String name, int age, float height, double weight, char sex, boolean allow) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.weight = weight;
        this.sex = sex;
        this.allow = allow;
    }

    public String getName() { return name;}

    public int getAge() {  return age; }

    public float getHeight() { return height;}

    public double getWeight() {return weight;}

    public char getSex() {return sex;}

    public boolean isAllow() { return allow;}

    //此处添加了注解,说明此处返回的是一个POJO需要迭代处理
    @NeedIterative
    public People getPeople() { return new People("李亚伟",12); }

需要返回的对象POJO对象是People类的代码内容为

public class People{
    private String people;
    private int work;

    public People(String people, int work) {
        this.people = people;
        this.work = work;
    }

    public String getPeople() { return people; }

    public int getWork() { return work; }
}

反射返回对象

代码很见到,都是Class等常见的API,这里不做赘述。

    public static  Map toMap(Object obj) throws Exception {
        Class clazz = obj.getClass();
        //获得属性
        Field[] fields = obj.getClass().getDeclaredFields();
        HashMap hashMap = new HashMap(fields.length);
        for (Field field : fields) {
            PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
            //获得get方法
            Method getMethod = pd.getReadMethod();
            //执行get方法返回一个Object
            Object exeValue = getMethod.invoke(obj);
            String key = dealMethodName(getMethod.getName());
            NeedIterative annotation = getMethod.getAnnotation(NeedIterative.class);
             //获取的注解不为空,那么说明此处返回的结果是对象,那么需要迭代处理
            if (annotation != null) {
                exeValue = toMap(exeValue);
            }
            hashMap.put(key, exeValue);
        }
        return hashMap;
    }

输出结果

由此可见,不管是基本数据类型,还是POJO类都能正常的转换。

断点数据类型查看:

image

sout输出效果如下:

{
        allow=true, 
        sex=m,
        name=周涛,
        weight=12.23,
        people={
                people=李亚伟, 
                work=12
                },
        age=23,
        height=12.12
}

更多关于Java方面的文章,欢迎访问燕归来https://www.zhoutao123.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,408评论 19 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 13,867评论 6 13
  • 1.历史作业本 2.历史小感想 3.生物世纪金榜 简书里的以过来人的方式告诉我了一些道理 …很惊讶…很感动…谢谢你...
    OngZiyang阅读 1,839评论 0 0
  • 掩耳情话,就是一个人唱完所有的对白。 金色阳光,地平线,海鸥 闭着眼,都能触摸到幸福。 携手路过玫瑰花丛,离开时,...
    轻文艺Milo阅读 1,651评论 0 0
  • 前几天我有个做技术的朋友,把自己的微信好友从2700多减少到175个。他老婆听说了他把 BAT 的几百人全都删除了...
    正记录Beta阅读 3,226评论 12 30