直接进入主题吧
首先是造对象,创建了一个user对象,包含了user2对象
@Data
public class User {
private String name;
private Integer age;
private double weight;
private String gender;
private User2 user2;
public User() {
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User2 {
private String name;
private Integer age;
}
map给了4个key,其中class在user属性中不存在;
user对象中gender在map中也不存在。
把user和map丢进reflex方法中,接下来主要看reflex的逻辑。
public static void main(String[] args) {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Jack");
map.put("age", 18);
map.put("weight", 175.5);
map.put("class", "一班");
User user = new User();
reflex(user, map);
System.out.println("user = " + user);
}
- 先获取Class对象,利用反射获取所有字段包括私有的,遍历字段
- 判断字段的类型,主要分为:基本类型、基本类型的包装类、String、List、Map、自定义对象
- 因可能出现字段名相同,但类型不一致的情况,这种情况不能赋值。
- 当type为基本数据类型时,map中的value为对应的类或包装类直接set
- 当type的类型在list中,赋值前需要判断与value类型是否一致
- 最后,当type为自定义类型时,这个时候通过获取构造器,得到对应对象,把对应对象进行递归处理
- 重点还有一个,因user和user2中都有name和age属性,这个时候默认是都赋值的,且值相同
//反射
public static <T> void reflex(T obj, Map<String, Object> map) {
List<Class> list = Lists.newArrayList(Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, String.class, Collection.class, List.class, Map.class);
try {
Class<?> cla = obj.getClass();
Field[] fields = cla.getDeclaredFields();
for (Field field : fields) {
Class<?> type = field.getType();
field.setAccessible(true);
System.out.println("filedType = " + type);
//判断是否为基本类型
if (type.isPrimitive()) {
String name = field.getName();
System.out.println("filedName = " + name);
Object value = map.get(name);
if (value != null && type.toString().equals(value.getClass().getSimpleName().toLowerCase())) {
//类中可能会包含对象或父类,可能会出现重复属性,只要字段名相同,默认都赋值
field.set(obj, value);
}
} else if (list.contains(type)) {
String name = field.getName();
System.out.println("filedName = " + name);
Object value = map.get(name);
if (value != null && value.getClass() == type) {
//类中可能会包含对象或父类,可能会出现重复属性,只要字段名相同,默认都赋值
field.set(obj, value);
}
} else {
Constructor<?> declaredConstructor1 = type.getDeclaredConstructor();
declaredConstructor1.setAccessible(true);
Object obj1 = declaredConstructor1.newInstance();
reflex(obj1, map);
field.set(obj, obj1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
第一次写,有不对的地方欢迎评论区交流,互相学习。