java 反射實現不同對象相同屬性值復制


1、此方法會過濾final字段

2、此方法會過濾對象字段

3、此方法會兼容同對象之間、不同對象之間屬性值復制

package com.bin.design.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

import com.bin.design.domain.People;
import com.bin.design.domain.User;

public class Tools {
    /**
     * 對象相同屬性copy
     * 
     * @param obj
     * @param toResult
     * @return
     * @throws Exception
     *             轉換報錯
     */
    public static <T> T cloneObj(Object obj, Class<T> toResult) {
        if (obj == null) {
            return null;
        }
        try {
            T t = toResult.newInstance();
            Field[] fields = toResult.getDeclaredFields();
            for (Field field : fields) {
                 field.setAccessible(true);//修改訪問權限
                if (Modifier.isFinal(field.getModifiers()))
                    continue;
                if (isWrapType(field)) {
                    String firstLetter = field.getName().substring(0, 1).toUpperCase(); // 首字母大寫
                    String getMethodName = "get" + firstLetter + field.getName().substring(1);
                    String setMethodName = "set" + firstLetter + field.getName().substring(1);
                    Method getMethod = obj.getClass().getMethod(getMethodName);   //從源對象獲取get方法
                    Method setMethod = toResult.getMethod(setMethodName, new Class[] { field.getType() }); //從目標對象獲取set方法
                    
                    //如果get 和 set方法都從一個對象中獲取會出現object is not an instance of declaring class這個錯誤
                    //like: User{name} People{name} 
                    //因為如果從源對象中獲取,在setMethod.invoke調用的時候,雖然名字相同,會由於類的不同,導致
                    //調用的方法卻不是目標對象中應有的方法。實際就是:getMethod = com.package.User.getName();setMethod = com.package.User.setName();
                    //而setMethod.invoke調用的結果就變成 People.setName() == People.(com.package.User.setName())
                    //這里的setName卻不是People該有的,so 報錯了
                    //同理,如果從目標對象中獲取,在getMethod.invoke調用的時候也會出錯。
                    //因此,對於getMethod和setMethod的獲取應該根據源對象和目標對象區別對待。
                    
                    //當然如果只是進行單獨的對象復制,就不用擔心會出現調用不屬於本身的方法,也就不用區分對象get和set
                    
                    Object value = getMethod.invoke(obj); // get 獲取的是源對象的值
                    setMethod.invoke(t, new Object[] { value }); // set 設置的是目標對象的值
                }
            }
            return t;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 是否是基本類型、包裝類型、String類型
     */
    private static boolean isWrapType(Field field) {
        String[] types = { "java.lang.Integer", "java.lang.Double", "java.lang.Float", "java.lang.Long",
                "java.lang.Short", "java.lang.Byte", "java.lang.Boolean", "java.lang.Char", "java.lang.String", "int",
                "double", "long", "short", "byte", "boolean", "char", "float" };
        List<String> typeList = Arrays.asList(types);
        return typeList.contains(field.getType().getName()) ? true : false;
    }

    
    public static void main(String[] args) {
        User user = new User();
        user.setName("AAA");
        user.setPassword("vvv");
        System.out.println("1"+user.getName()+user.getPassword());
        
        People people =new People();
        System.out.println("2"+people.getName());
        
        User users = cloneObj(user,User.class);
        System.out.println("3"+users.getName());
        
        People p = cloneObj(user,People.class);
        System.out.println("4"+p.getName());
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM