git地址,欢迎来star
https://github.com/sun-junchen/data-utils
data 工具,目前实现了拷贝
package com.example.entity;
import com.example.common.ErrorCode;
import com.example.exception.BusinessException;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.*;
import java.util.function.Consumer;
public interface BaseData {
String GET = "get";
String SET = "set";
default <V> V asTargetObject(Class<V> clazz, Consumer<V> consumer) {
V v = this.asTargetObject(clazz);
consumer.accept(v);
return v;
}
default <V> V asTargetObject(Class<V> clazz) {
try {
Field[] declaredFields = clazz.getDeclaredFields();
Constructor<V> constructor = clazz.getConstructor();
V v = constructor.newInstance();
for (Field declaredField : declaredFields) convert(declaredField, v);
return v;
} catch (ReflectiveOperationException e) {
throw new BusinessException(ErrorCode.CAST_OBJECT_ERROR);
}
}
default void convert(Field field, Object vo) {
try {
Field source = this.getClass().getDeclaredField(field.getName());
ReflectionUtils.makeAccessible(field);
ReflectionUtils.makeAccessible(source);
Method sourceGetter = this.getClass().getMethod(GET + capitalize(field.getName()));
Method targetSetter = vo.getClass().getMethod(SET + capitalize(field.getName()), field.getType());
Object value = sourceGetter.invoke(this);
targetSetter.invoke(vo, value);
} catch (NoSuchFieldException | InvocationTargetException | IllegalAccessException | NoSuchMethodException ignored) {
// 这里ignored 原因是
// 两个类的字段数量不一样的时候,会报 java.lang.NoSuchFieldException
// 但是多出来的字段我们是可以处理的
}
}
default String capitalize(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
}
项目中有测试方法
- 实现对象深拷贝
- 实现对象Collection 深拷贝(List Set …)
实现步骤
- dto 实现 BaseData接口
- dto.asViewObject(Target.class);
- 如果 Target 还有其他字段 也可以自定义,例如githu项目测试用例中的genderNum(只是简单举的例子,按照项目实际来)
AccountVO accountVO = accountDTO.asTargetObject(AccountVO.class,v->{
v.setGenderNum(Objects.equals(accountDTO.getGender(), "男") ? "1" : "0");
});
注意
两个类 相同的字段名的字段类型 必须完全一样!!!