解题思路:
- 遍历
bean
的字段,每遍历一个字段都遍历一次clazz
的字段判断是否clazz
有对应的字段(双重遍历/遍历里面嵌套遍历)
- 遍历
clazz
的字段并存储到Map<String,Field>
中,之后遍历bean
的所有字段,每一个字段都先判断再拷贝(先遍历后遍历)
- 只遍历
bean
的所有字段,判断class是否有对应的字段再拷贝(只遍历一次)
方法2
//编写工具类BeanUtils
public class BeanUtils {
//拷贝属性的方法,bean是被拷贝的的对象,clazz是要拷贝的class
public static <T> T copyProperties(Object bean, Class<T> clazz) {
//实现拷贝逻辑, 只要class中有属性名和bean相同的就执行拷贝
// 获取clazz的所有字段并存储到Map<字段名,字段>中
Map<String, Field> clazzFields = new HashMap<>();
for (Field field : clazz.getDeclaredFields()) {
clazzFields.put(field.getName(), field);
}
try {
// 创建一个clazz对象用于返回结果
T t = clazz.newInstance();
// 获取bean的类型对象
Class<?> beanClass = bean.getClass();
// 遍历bean的所有字段
for (Field field : beanClass.getDeclaredFields()) {
// 判断class是否有对应的字段
if (clazzFields.containsKey(field.getName())) {
field.setAccessible(true);
Field clazzField = clazzFields.get(field.getName());
clazzField.setAccessible(true);
clazzField.set(t, field.get(bean));
}
}
return t;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
方法3
//编写工具类BeanUtils
public class BeanUtils {
//拷贝属性的方法,bean是被拷贝的的对象,clazz是要拷贝的class
public static <T> T copyProperties(Object bean, Class<T> clazz) {
//实现拷贝逻辑, 只要class中有属性名和bean相同的就执行拷贝
try {
// 创建一个clazz对象用于返回结果
T t = clazz.newInstance();
// 获取bean的类型对象
Class<?> beanClass = bean.getClass();
// 遍历bean的所有字段
for (Field field : beanClass.getDeclaredFields()) {
// 判断class是否有对应的字段
field.setAccessible(true);
Field clazzField = getField(clazz, field.getName());
if (clazzField != null) {
clazzField.setAccessible(true);
clazzField.set(t, field.get(bean));
}
}
return t;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 判断class是否有对应的字段
* @param clazz
* @param name
* @return
*/
private static Field getField(Class<?> clazz, String name) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException e) {
return null;
}
}
}