欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中,循环对bean的属性进行赋值

程序员文章站 2022-05-23 21:56:31
...

项目背景

我们开发过程中会碰到这样一类问题,就是数据层或三方接口返回的Bean对象需要转换重新装换一下我们需要的对象。我们通常的做法就是通过getter/setter方法进行一个一个进行赋值,这样的话书写起来太复杂了,并且太重复了。我尝试写了一个工具类,能够对各种场景下的对象进行相互赋值。

功能介绍

  • 可以为将要赋值的对象进行单个单个的按顺序赋值
  • 通过传递的属性的index(就是他是第几个属性)获取本属性的值
  • 返回对象中属性的数量
  • 两个对象之间相互拷贝属性值
  • 传递一个list,遍历bean进行赋值
  • 传递一个数组,对对象进行赋值
  • 返回一个对象的属性值集合
  • 返回一个对象的属性值数组

注意注意注意!!!

getDeclaredFields方法不能保证字段声明的顺序进行返回,但是基本上会按照这个顺序的。所以以下的方法是建立在返回正确的顺序上的基础上的,但是两个对象相互拷贝是没有问题的。

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author haoyan.shi
 * 想设计一个能够解析一个bean的全部属性并按照顺序进行遍历
 */
public class ObjectUtils {

    /**
     * 按照属性的顺序赋值。可接受null,但是不能跳过某个属性进行赋值。就是说就算
     * 有一个值为空,那你也要传递进行null
     *
     * @param target
     * @param value
     * @param <E>
     * @return
     */
    public static <E> E forEachSetValue(E target, Object value) {
        if (target == null) {
            return target;
        }
        List<Field> fields = new ArrayList<>();
        try {
            // 1.解析出所有的属性
            Field[] declaredFields = target.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                fields.add(declaredField);
            }
            // 2.把每个属性放入一个集合中
            if (fields.size() <= 0) {
                return target;
            }
            while (fields.get(0).get(target) != null) {
                fields.remove(0);
            }
            Field field = fields.get(0);
            field.set(target, value);
            fields.remove(0);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return target;
    }

    /**
     * 本方法为了遍历索引进行赋值
     *
     * @param e
     * @param index
     * @return
     */
    public static Object forEachGetValue(Object e, int index) {
        try {
            Field[] declaredFields = e.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
            }
            return declaredFields[index].get(e);
        } catch (IllegalAccessException illegalAccessException) {
            illegalAccessException.printStackTrace();
        }
        return e;
    }

    public static int size(Object o) {
        if (o == null) {
            return 0;
        }
        Field[] declaredFields = o.getClass().getDeclaredFields();
        return declaredFields.length;
    }

    /**
     * 本方法是为了把已经有值得对象中属性名相同的名属性赋值到没有值得对象用。
     *
     * @param target
     * @param value
     */
    public static <E> E copyValueFromObject(E target, Object value) {
        if (target == null || value == null) {
            return null;
        }
        Field[] vs = target.getClass().getDeclaredFields();
        Field[] ts = value.getClass().getDeclaredFields();

        try {
            for (int i = 0; i < vs.length; i++) {
                for (int j = 0; j < ts.length; j++) {
                    if (vs[i].getName().equals(ts[j])) {
                        ts[j].set(target, vs[i].get(value));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return target;
    }

    /**
     * 这个方法能把list中的值按照顺序设置到目标对象中
     *
     * @param target
     * @param value
     * @param <E>
     * @return
     */
    public static <E> E forEachSetValueFromList(E target, List value) {

        if (target == null || value == null || value.size() == 0) {
            return target;
        }
        Field[] ts = target.getClass().getDeclaredFields();
        try {
            for (int i = 0; i < ts.length; i++) {
                ts[i].set(target, value.get(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return target;
    }

    /**
     * 从数组中进行设置值
     *
     * @param target
     * @param value
     * @param <E>
     * @return
     */
    public static <E> E forEachSetValueFromArray(E target, Object[] value) {

        if (target == null || value == null || value.length == 0) {
            return target;
        }
        Field[] ts = target.getClass().getDeclaredFields();
        try {
            for (int i = 0; i < ts.length; i++) {
                ts[i].set(target, value[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return target;
    }


    public static Object[] getArrayValue(Object o) {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        Object[] result = new Object[declaredFields.length];
        try {
            for (int i = 0; i < declaredFields.length; i++) {
                result[i] = declaredFields[i].get(o);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static List getListValue(Object o) {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        List result = new ArrayList(declaredFields.length);
        try {
            for (int i = 0; i < declaredFields.length; i++) {
                result.add(declaredFields[i].get(o));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

}

后期扩展:
1.我们可以定义一些注解,进行属性匹配。注入值更精确。
2.还可以用jdk1.8中的函数接口,进行赋值。
3.甚至都可以作为jdk的新特性去扩展这个功能。