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

Posted

tags:

篇首语:本文由小常识网(cha138.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类都能正常的转换。

断点数据类型查看:
技术分享图片
sout输出效果如下:

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

感兴趣可以加Java架构师群获取Java工程化、高性能及分布式、高性能、深入浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的直播免费学习权限 都是大牛带飞 让你少走很多的弯路的 群..号是:855801563 对了 小白勿进 最好是有开发经验

注:加群要求

1、具有工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加。

2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。

3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。

4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。

5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!

以上是关于利用反射机制实现对象转Map集合的主要内容,如果未能解决你的问题,请参考以下文章

利用java反射将结果集封装成为对象和对象集合

对象Bean与Map互转问题

java利用反射机制判断对象的属性是否为空

[转]Java反射机制详解

如何利用java的反射机制动态创建对象

代码片段 - Golang 实现集合操作