import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @description: 對象之間copy
* @author: 作者
* @data: 2018-01-01
*/
public class BeanUtils {
/**
* 創建新的對象,並將源類中對應的屬性複製到新的對象中
* @param source 源對象
* @param target 目標對象
* @param <T> 目標對象的類型
* @return
*/
public static <T> T copyNewInstance(Object source, Class<T> target) {
if (source == null) {
return null;
}
T t;
try {
t = target.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// 如果創建對象失敗,則直接放回 null
return null;
}
copyToObject(source, t, false);
return t;
}
/**
* copy源類中對應的屬性到目標對象,默認爲不拷貝null對象
* @param source 源對象
* @param target 目標對象
*/
public static void copyToObject(Object source, Object target) {
copyToObject(source, target, false);
}
/**
* copy源類中對應的屬性到目標對象
* @param source 源對象
* @param target 目標對象
* @param copyNull 是否copy源對象中的null屬性
*/
public static void copyToObject(Object source, Object target, boolean copyNull) {
if(source == null || target == null)
return;
Field[] fields = target.getClass().getDeclaredFields();
for (Field field : fields) {
// 修改訪問權限
field.setAccessible(true);
// 判斷本字段是否有複製的條件
if(!isField(source.getClass(), field)) {
continue;
}
// 將首字母轉換爲大寫
String firstLetter = field.getName().substring(0, 1).toUpperCase();
// 添加set,構建爲set方法的名字
String getMethodName = "get" + firstLetter + field.getName().substring(1);
// 添加get。構建爲get方法的名字
String setMethodName = "set" + firstLetter + field.getName().substring(1);
try {
// 從源對象中獲取get方法
Method getMethod = source.getClass().getMethod(getMethodName);
// 從目標對象獲取set方法
Method setMethod = target.getClass().getMethod(setMethodName, new Class[] { field.getType() });
// 使用源的get方法,拿到對應的值
Object value = getMethod.invoke(source);
// 如果源對象中無值,則直接跳過複製
if(!copyNull && value == null)
continue;
// 將對應的值使用目標對象的set方法設置進去
setMethod.invoke(target, new Object[] { value });
} catch (NoSuchMethodException |IllegalAccessException | InvocationTargetException e) {
// 源方法的get方法不存在,或者目標方法的set方法不存在,導致執行失敗
// 直接跳過
}
}
}
/**
* 檢測源字段和目標字段是否有複製條件
* @param source 源對象
* @param target 目標字段
* @return
*/
public static boolean isField(Class source, Field target) {
// 檢測目標字段是否被 final 修飾
if(Modifier.isFinal(target.getModifiers())) {
return false;
}
String fieldName = target.getName();
try {
// 檢測原字段中是否存在目標字段,並且類型是否相同
Field field = source.getDeclaredField(fieldName);
return target.getType() == field.getType();
} catch (NoSuchFieldException e) {
return false;
}
}
/**
* 創建新的對象,並將源類中對應的屬性複製到新的對象中
* @param source 源對象
* @param target 目標對象
* @param fieldNames 要複製的字段
* @param <T> 目標對象屬性
* @return
*/
public static <T> T copyNewInstance(Object source, Class<T> target, String... fieldNames) {
if (source == null) {
return null;
}
T t;
try {
t = target.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// 如果創建對象失敗,則直接放回 null
return null;
}
copyToObject(source, t, false, fieldNames);
return t;
}
/**
* copy源類中對應的屬性到目標對象,默認爲不拷貝null對象
* @param source 源對象
* @param target 目標對象
* @param fieldNames 需要複製的字段
*/
public static void copyToObject(Object source, Object target, String... fieldNames) {
copyToObject(source, target, false, fieldNames);
}
/**
* copy源類中對應的屬性到目標對象
* @param source 源對象
* @param target 目標對象
* @param copyNull 是否copy源對象中的null屬性
* @param fieldNames 需要複製的字段
*/
public static void copyToObject(Object source, Object target, boolean copyNull, String... fieldNames) {
if(source == null || target == null)
return;
for (String fieldName : fieldNames) {
try {
Field field = target.getClass().getDeclaredField(fieldName);
// 修改訪問權限
field.setAccessible(true);
// 判斷本字段是否有複製的條件
if(!isField(source.getClass(), field)) {
continue;
}
// 將首字母轉換爲大寫
String firstLetter = fieldName.substring(0, 1).toUpperCase();
// 添加set,構建爲set方法的名字
String getMethodName = "get" + firstLetter + field.getName().substring(1);
// 添加get。構建爲get方法的名字
String setMethodName = "set" + firstLetter + field.getName().substring(1);
// 從源對象中獲取get方法
Method getMethod = source.getClass().getMethod(getMethodName);
// 從目標對象獲取set方法
Method setMethod = target.getClass().getMethod(setMethodName, new Class[] { field.getType() });
// 使用源的get方法,拿到對應的值
Object value = getMethod.invoke(source);
// 如果源對象中無值,則直接跳過複製
if(!copyNull && value == null)
continue;
// 將對應的值使用目標對象的set方法設置進去
setMethod.invoke(target, new Object[] { value });
} catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
// 沒有此字段,
// 源方法的get方法不存在,或者目標方法的set方法不存在,導致執行失敗
// 直接跳過
}
}
}
}
一個工具,可用於對象之間的copy
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.