简单的记录,方便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()。其实原理和上面一样就是利用的反射。
集合类型的拷贝也是一样的了,先把集合对象处理为流,对其中的每个对象都执行到拷贝,然后拷贝完后收集起来返回一个拷贝完成后的新的集合。