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());
    }
}
时间: 2024-08-02 15:10:37

java 反射实现不同对象相同属性值复制的相关文章

利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils

有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 package com.banksteel.util; import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.ut

Java反射设置和访问私有属性值

越学习到后面,越感觉java反射机制很重要,必须精通,要不框架那块比较难自己动手实现,回过头温习一下反射机制,查漏补缺 今天尝试了一下通过反射访问和设置类的私有属性(不设置settesr和getters),比较容易理解,代码一贴就知道了 下面是po代码: package cn.liangqinghai.reflect; public class Beans1 { public Beans1(){ System.out.println("无参构造调用"); } public Beans1

Java中List根据对象的属性值进行数据库group by功能的操作

1 public class test { 2 public static void main(String[] args) { 3 4 List<Bill> list = new test().setObject(); 5 6 Set<String> set = new HashSet(); 7 8 for (Bill bills : list) { 9 set.add(bills.getTradeTime().substring(0, 8)); 10 } 11 12 List

java 反射获取类的静态属性值

public class AppTest { private NodeClass nodeClass; public static String hehe = "hehe"; public String xixi = "xixi"; public void test() { Field[] fields = AppTest.class.getDeclaredFields(); try { for (Field field : fields) { field.setA

利用反射机制,对对象的属性值进行自动设置

import java.lang.reflect.Method; /** * 对象的属性值自动设置,利用反射机制 */ public class AutoSet { /** * 将源对象的属性值赋值到目标对象,属性名一致,且源对象有get方法,目标对象有set方法 * @param src 源对象 * @param target 目标对象 * @return 赋值后的目标对象 */ public static Object autoGetterAndSetter(Object src, Obje

java反射获取对象的属性值和对象属性中的子属性值

近段时间在做web项目,前端使用的是jQuery EasyUI. 为方便需要,准备做一个前端通用的Datagird导出Excel功能,博主也考虑过思路和最终功能,1.前端选中行导出:2.当前页导出:3.当前过滤条件导出. 想偷懒在网上找找已有的代码改改,发现大部分只能满足个别需求,使用JS导出只能满足前端,使用代码才能实现3功能. ...... 好了,说了一堆废话,回归正题,本文是在做通用自定义字段导出时所需要,根据属性名去查找对象和子对象,找到对应属性值,抓取回来放到Excel中. 直接上代码

【java】【反射】反射实现判断发生了修改操作,判断两个对象是否发生属性值的变更,判断两个List集合内对象的属性值是否发生变更

java的反射实现: 判断发生了修改操作,判断两个对象是否发生属性值的变更,判断两个List集合内对象的属性值是否发生变更 今日份代码: package com.sxd.streamTest; import java.lang.reflect.Field; import java.util.*; /** * @ClassName Test * @Description 判断发生了修改操作,判断两个对象是否发生属性值的变更,判断两个List集合内对象的属性值是否发生变更 * @Author sxd

通过java反射获取任意对象的字段名及字段值

import java.lang.reflect.Field; public class ReflectClass3 { /** * @param args */ public static void main(String[] args) { Person p = new Person(1, "ctl", true, 'c', 2.0f, 2.0, 1L, (short) 1, (byte) 1); p.setId(0); p.setName("张三"); p.s

java利用反射机制判断对象的属性是否为空

java利用反射机制判断对象的属性是否为空: Map<String,String> validateMap = new LinkedHashMap<String, String>(); validateMap.put("serial", "编号");validateMap.put("major", "专业"); public static <T> String validateFiledIs