一個工具,可用於對象之間的copy

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方法不存在,導致執行失敗
                // 直接跳過
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章