JavaBean 属性copy

1.spring 中BeanUtils.copyProperties()
2.apache commons-beanutils 中BeanUtils.copyProperties()
3.apache commons-beanutils PropertyUtils.copyProperties(),三者比较
org.springframework.beans.BeanUtils与org.apache.commons.beanutils.BeanUtils都提供了copyProperties方法,作用是将一个Bean对象中的数据封装到另一个属性结构相似的Bean对象中
差异比较
1)两者的copyProperties方法参数位置不同
  org.springframework.beans.BeanUtils:  copyProperties(source, target)
  org.apache.commons.beanutils.BeanUtils:  copyProperties(target, source)
2)要求两个Bean的属性名相同,且有对应的setXxx方法和getXxx方法。其实底层原理是使用source的getXxx方法和target的setXxx方法
3)source有的属性而target没有的属性,不会封装到target对象中;
  target有的属性而source没有的属性,会封装到target中,数据为默认值(注意基本类型默认值与引用类型默认值不同)
4)类型转换问题
  a)基本类型与其对应的封装类型可以相互转换
  b)org.springframework.beans.BeanUtils
  与org.apache.commons.beanutils.BeanUtils对于String和Date类型转换的情况是不同的

日期转换注意事项
a. org.springframework.beans.BeanUtils.copyProperties
不可以将java.util.Date类型转换成String类型
b. org.apache.commons.beanutils.BeanUtils.copyProperties
可以将java.util.Date/java.sql.Date类型转换成String类型,但是转换后二者格式是不同的
测试效果:
java.util.Date–>String
[id=10,name=姓名,email=,createTime=Thu Jan 01 08:00:00 CST 1970]
java.sql.Date–>String
[id=10,name=姓名,email=,createTime=1970-01-01]

c . 无论是org.springframework.beans.BeanUtils
还是org.apache.commons.beanutils.BeanUtils,默认情况下都不能将String类型转成Date类型

高性能反射:reflectasm.jar
实现属性copy案例
package com.git.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.esotericsoftware.reflectasm.MethodAccess;
@SuppressWarnings(“rawtypes”)
public class Util {

private static String SET="set";
private static String GET="get";
private static Map<Class, MethodAccess> methodMap = new HashMap<Class, MethodAccess>(); 
private static Map<String, Integer> methodIndexMap = new HashMap<String, Integer>();  
private static Map<Class, List<String>> fieldMap = new HashMap<Class, List<String>>();  

 public static void copyProperties(Object desc, Object orgi) {  
     MethodAccess descMethodAccess = methodMap.get(desc.getClass()); 
     if(descMethodAccess==null){
         descMethodAccess=cache(desc);
     }

      MethodAccess orgiMethodAccess = methodMap.get(orgi.getClass());  
     if(orgiMethodAccess==null){
         orgiMethodAccess = cache(orgi);
     }

      List<String> fieldList = fieldMap.get(orgi.getClass());  
        for (String field : fieldList) {  
            String getKey = orgi.getClass().getName() + "." + GET + field;  
            String setkey = desc.getClass().getName() + "." + SET + field;  
            Integer setIndex = methodIndexMap.get(setkey);  
            if (setIndex != null) {  
                int getIndex = methodIndexMap.get(getKey);  
                // 参数一需要反射的对象  
                // 参数二class.getDeclaredMethods 对应方法的index  
                // 参数对三象集合  
                descMethodAccess.invoke(desc, setIndex.intValue(),orgiMethodAccess.invoke(orgi, getIndex));  
            }  
        }  

 }

 public static MethodAccess cache(Object orgi) {  
     synchronized (orgi.getClass()) {  
         //产生对象访问类
         MethodAccess methodAccess = MethodAccess.get(orgi.getClass()); 
         Field[] fields = orgi.getClass().getDeclaredFields();
         List<String> fieldList = new ArrayList<String>(fields.length);  
         for (Field field : fields) {  
             //私有非静态变量
             if (Modifier.isPrivate(field.getModifiers())  
                        && !Modifier.isStatic(field.getModifiers())){
                 //获取属性名称
                String fieldName = StringUtils.capitalize(field.getName());
                //获取get/set方法下标
                int getIndex = methodAccess.getIndex(GET+fieldName);
                int setIndex = methodAccess.getIndex(SET+fieldName);
                //将类名get/set方法名,下标注册到map中
                methodIndexMap.put(orgi.getClass().getName()+"."+GET+fieldName, getIndex);
                methodIndexMap.put(orgi.getClass().getName()+"."+SET+fieldName, setIndex);
                 // 将属性名称放入集合里
                fieldList.add(fieldName);

             }
         }
         //将类名,属性名称注册到map中  
         fieldMap.put(orgi.getClass(), fieldList);
         methodMap.put(orgi.getClass(), methodAccess);
         return methodAccess;
     }
 }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值