1.需求
现在有两个类,它们拥有相同的字段,但他们在某些字段上,一边是String.class类型,另一边是枚举类型,且String类型的值可映射到相应字段的枚举值上;
public static <F, T> void fillWithoutEnum(F fromObjWithoutEnum, T toObjWithEnum) {
Field[] fields = toObjWithEnum.getClass().getDeclaredFields();
for (Field field : fields) {
//如果是final类型,就不用注入了
if (java.lang.reflect.Modifier.isFinal(field.getModifiers())) {
continue;
}
try {
String fieldName = field.getName().substring(0, 1).toUpperCase(Locale.ROOT) + field.getName().substring(1);
Method method0 = toObjWithEnum.getClass().getDeclaredMethod("set" + fieldName, field.getType());
Method method1 = fromObjWithoutEnum.getClass().getDeclaredMethod("get" + fieldName);
Object invoke = method1.invoke(fromObjWithoutEnum);
if (invoke == null) {
continue;
}
//判断该字段是否是枚举类型
if (field.getType() == Enum.class || field.getType().getEnumConstants() != null) {
Type genericType = field.getGenericType();
String typeName = genericType.getTypeName();
//如果是 Enum<ColorEnum>形式,则提取出来
if (typeName.startsWith(ENUM_PREFIX)) {
typeName = typeName.substring(ENUM_PREFIX.length(), typeName.length() - 1);
}
//反射调用方法
Class<?> clazz = Class.forName(typeName);
Method method = clazz.getMethod("valueOf", method1.getReturnType());
//String换Enum
Object ret = method.invoke(null, invoke);
method0.invoke(toObjWithEnum, ret);
continue;
}
method0.invoke(toObjWithEnum, invoke);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | ClassNotFoundException e) {
logger.error("字段注入失败:{}", e);
}
}
}
public static void main(String[] args) {
Obj0 obj0 = new Obj0();
Obj1 obj1= new Obj1("liyuan",20,"DEFAULT");
fillWithoutEnum(obj1, obj0);
System.out.println(obj0);
}
package seewo;
public class Obj0 {
private String name;
private Integer age;
private Enum<AuditActionType> auditActionType;
public Obj0(String name, Integer age, AuditActionType auditActionType) {
this.name = name;
this.age = age;
this.auditActionType = auditActionType;
}
public Obj0() {
}
public Enum<AuditActionType> getAuditActionType() {
return auditActionType;
}
public void setAuditActionType(Enum<AuditActionType> auditActionType) {
this.auditActionType = auditActionType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Obj0{" +
"name='" + name + '\'' +
", age=" + age +
", auditActionType=" + auditActionType +
'}';
}
}
package seewo;
public class Obj1 {
private String name;
private Integer age;
private String auditActionType;
public String getAuditActionType() {
return auditActionType;
}
public void setAuditActionType(String auditActionType) {
this.auditActionType = auditActionType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Obj1{" +
"name='" + name + '\'' +
", age=" + age +
", auditActionType='" + auditActionType + '\'' +
'}';
}
public Obj1(String name, Integer age, String auditActionType) {
this.name = name;
this.age = age;
this.auditActionType = auditActionType;
}
public Obj1() {
}
public void setAge(Integer age) {
this.age = age;
}
}