diff --git a/src/main/java/com/yexuejc/base/util/ObjUtil.java b/src/main/java/com/yexuejc/base/util/ObjUtil.java
index 51f70fa..d11c9ca 100644
--- a/src/main/java/com/yexuejc/base/util/ObjUtil.java
+++ b/src/main/java/com/yexuejc/base/util/ObjUtil.java
@@ -4,9 +4,11 @@ import com.yexuejc.base.annotation.ToUeProperty;
import java.io.*;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
+import java.util.stream.Collectors;
/**
* 对象工具:对类的操作
@@ -260,4 +262,145 @@ public class ObjUtil {
return outer;
}
+ /**
+ * 复制对象属性值,包含父类 (不需要getter和setter)
+ *
includeField和excludeField同时传入,走包含逻辑,
+ *
+ * @param source 源对象
+ * @param targetClass 目标对象class
+ * @param includeField 包含对象
+ * @param excludeField 排除对象
+ * @param
+ * @param
+ * @return 目标对象
+ * @throws Exception
+ */
+ public static O copy(I source, Class targetClass, List includeField, List excludeField) throws Exception {
+ List allFields = getAllFields(source.getClass());
+ O o = targetClass.getDeclaredConstructor().newInstance();
+ if (StrUtil.isNotEmpty(excludeField) && StrUtil.isEmpty(includeField)) {
+ allFields = allFields.stream().filter(f -> !excludeField.contains(f.getName())).collect(Collectors.toList());
+ }
+ if (StrUtil.isNotEmpty(includeField)) {
+ allFields = allFields.stream().filter(f -> includeField.contains(f.getName())).collect(Collectors.toList());
+ }
+ allFields.forEach(f -> {
+ try {
+ try {
+ Field field = targetClass.getDeclaredField(f.getName());
+ if (field != null) {
+ f.setAccessible(true);
+ Object v = f.get(source);
+ f.setAccessible(false);
+ field.setAccessible(true);
+ field.set(o, v);
+ field.setAccessible(false);
+ }
+ } catch (NoSuchFieldException e) {
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ return o;
+ }
+
+ /**
+ * 深度复制对象
+ * 获取source的所有getXxx。xxx作为属性,且包含父类的getXxx
+ * 查找target的xxx属性,进行反射设值
+ *
+ * @param source 源对象
+ * @param targetClass 目标对象class
+ * @param invokeSetter 设置target属性值时,是否使用setter方法设置
+ * @param
+ * @param
+ * @return 目标对象
+ */
+ public static O copy(I source, Class targetClass, boolean invokeSetter) throws Exception {
+ List getterMethods = getAllGetterMethods(source.getClass(), "get");
+ O o = targetClass.getDeclaredConstructor().newInstance();
+ getterMethods.forEach(method -> {
+ try {
+ String fieldName = method.getName().replace("get", "");
+ Object v = method.invoke(source);
+ if (invokeSetter) {
+ try {
+ Method setterMethod = targetClass.getDeclaredMethod("set" + fieldName, method.getReturnType());
+ if (null != setterMethod) {
+ setterMethod.invoke(o, v);
+ }
+ } catch (NoSuchMethodException e) {
+ }
+ } else {
+ try {
+ Field field = targetClass.getDeclaredField(lowerCaseFirstChar(fieldName));
+ if (field != null) {
+ field.setAccessible(true);
+ field.set(o, v);
+ field.setAccessible(false);
+ }
+ } catch (NoSuchFieldException e) {
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ return o;
+ }
+
+ /**
+ * 获取所有方法,包含父类
+ *
+ * @param beanClass
+ * @param startsWith 方法的开头匹配(空,返回所有)
+ * @return
+ */
+ public static List getAllGetterMethods(Class> beanClass, String startsWith) {
+ List methodList = new ArrayList<>();
+ Method[] methods = beanClass.getDeclaredMethods();
+ if (StrUtil.isNotEmpty(startsWith)) {
+ methodList.addAll(Arrays.stream(methods)
+ .filter(method -> method.getName().startsWith(startsWith))
+ .collect(Collectors.toList()));
+ } else {
+ methodList.addAll(Arrays.asList(methods));
+ }
+ Class> superclass = beanClass.getSuperclass();
+ if (superclass != null) {
+ methodList.addAll(getAllGetterMethods(superclass, startsWith));
+ }
+ return methodList;
+ }
+
+ /**
+ * 获取所有属性,包含父类
+ *
+ * @param beanClass
+ * @return
+ */
+ public static List getAllFields(Class> beanClass) {
+ List fieldList = new ArrayList<>();
+ while (beanClass != null) {
+ fieldList.addAll(Arrays.asList(beanClass.getDeclaredFields()));
+ beanClass = beanClass.getSuperclass();
+ }
+ return fieldList;
+ }
+
+ /**
+ * 首字母小写
+ *
+ * @param str
+ * @return
+ */
+ public static String lowerCaseFirstChar(String str) {
+ if (str == null || str.length() == 0) {
+ return str;
+ } else {
+ return str.substring(0, 1).toLowerCase() + str.substring(1);
+ }
+ }
+
}