属性拷贝工具类封装

2023-02-26 16:36:41 浏览数 (1)

简单的记录,方便cv

一共分为单个对象类拷贝,和集合类型拷贝。属性拷贝主要就是用于封装一些必要的数据。

先来看简单的反射如何实现对象拷贝 这是一个工具类封装的一个现成的方法,内部实现的原理就是利用反射实现对象的拷贝。

来看我们普通的反射如何实现对象的拷贝。 下面这里是一个拷贝方法,参数是源对类和要拷贝的对象的字节码 .class

代码语言:javascript复制
  public static <T> T copy(Object source,Class<T> clz){
        //获取指定对象的Class对象
//      Class<T> clz = T;//Student.class
        /* 为什么要多加一个参数Class<T> clz?
         * 是因为泛型, 为了返回值直接是该对象, 而不是Object.
         */
        T newObj = null;
        try {
            //根据class对象创建当前类型的实例(空对象)
            newObj = clz.newInstance();
            //获取当前类中包含的所有属性
            Field[] fields = clz.getDeclaredFields();
            for (Field field : fields) {
                //拼接获取setter/getter方法的名称
                String setMethodName = "set" field.getName().substring(0, 1).toUpperCase() field.getName().substring(1);
                String getMethodName = "get" field.getName().substring(0, 1).toUpperCase() field.getName().substring(1);
                //根据方法名称获取方法对象
                Method method_set = clz.getMethod(setMethodName, field.getType());//setter方法
                Method method_get = clz.getMethod(getMethodName);//getter方法

                //执行源对象指定属性的getter方法,获取属性值
                Object returnval = method_get.invoke(source);
                //执行新对象的setter方法,将源对象的属性值设置给新对象
                method_set.invoke(newObj, returnval);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return newObj;
    }   

按照这个逻辑,我们就可以这样去做了。 下面是封装的工具类

代码语言:javascript复制
package com.jgdabc.utils;

import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 兰舟千帆
 * @version 1.0
 * @date 2023/1/24 19:57
 * @Description 功能描述:
 */
public class BeanCopyUtils {
    private BeanCopyUtils()
    {

    }
    public static <V> V copyBean(Object source,Class<V> clazz)  {
//        创建目标对象
//        实现属性拷贝
        V result = null;
        try {
            result = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        BeanUtils.copyProperties(source,result);
        return  result;
    }
    //集合类型的拷贝
    public static <O,V>List<V> copyBeanList(List<O>list,Class<V> clazz )
    {
        return list.stream().map(o -> copyBean(o, clazz)).collect(Collectors.toList());

    }

}

用到了一个 BeanUtils.copyProperties()。其实原理和上面一样就是利用的反射。

集合类型的拷贝也是一样的了,先把集合对象处理为流,对其中的每个对象都执行到拷贝,然后拷贝完后收集起来返回一个拷贝完成后的新的集合。

0 人点赞