mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-06-06 13:54:03 +08:00
[feat] ObjUtil 增加对象的深度copy
This commit is contained in:
parent
3ddd11f9c9
commit
0754660c45
@ -4,9 +4,11 @@ import com.yexuejc.base.annotation.ToUeProperty;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象工具:对类的操作
|
* 对象工具:对类的操作
|
||||||
@ -260,4 +262,145 @@ public class ObjUtil {
|
|||||||
return outer;
|
return outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制对象属性值,包含父类 (不需要getter和setter)
|
||||||
|
* <p>includeField和excludeField同时传入,走包含逻辑,</p>
|
||||||
|
*
|
||||||
|
* @param source 源对象
|
||||||
|
* @param targetClass 目标对象class
|
||||||
|
* @param includeField 包含对象
|
||||||
|
* @param excludeField 排除对象
|
||||||
|
* @param <I>
|
||||||
|
* @param <O>
|
||||||
|
* @return 目标对象
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static <I, O> O copy(I source, Class<O> targetClass, List<String> includeField, List<String> excludeField) throws Exception {
|
||||||
|
List<Field> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深度复制对象
|
||||||
|
* <p>获取source的所有getXxx。xxx作为属性,且包含父类的getXxx</p>
|
||||||
|
* <p>查找target的xxx属性,进行反射设值</p>
|
||||||
|
*
|
||||||
|
* @param source 源对象
|
||||||
|
* @param targetClass 目标对象class
|
||||||
|
* @param invokeSetter 设置target属性值时,是否使用setter方法设置
|
||||||
|
* @param <I>
|
||||||
|
* @param <O>
|
||||||
|
* @return 目标对象
|
||||||
|
*/
|
||||||
|
public static <I, O> O copy(I source, Class<O> targetClass, boolean invokeSetter) throws Exception {
|
||||||
|
List<Method> 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<Method> getAllGetterMethods(Class<?> beanClass, String startsWith) {
|
||||||
|
List<Method> 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<Field> getAllFields(Class<?> beanClass) {
|
||||||
|
List<Field> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user