码迷,mamicode.com
首页 > 其他好文 > 详细

通过反射克隆对象,对象复制(克隆),对象合并工具类 升级版

时间:2015-01-30 21:07:57      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

      先上代码,有时间再详说:

package com.kaiyuan.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 通用对象copy工具类
 * 
 * @author arron
 * @date 2015年1月9日 上午10:50:32
 * @version 1.0
 */
public class ObjectCopyUtil {

    private static final Logger logger = LoggerFactory.getLogger(ObjectCopyUtil.class);
    
	
	/**
	 * 拷贝对象方法(适合同一类型的对象复制,但结果需强制转换)
	 * 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static Object copy(Object objSource) throws InstantiationException, IllegalAccessException{
        return copy(objSource,objSource.getClass());
	}
	
	/**
	 * 拷贝对象方法(适合同一类型的对象复制)
	 * 
	 * @param objSource 源对象
	 * @param clazz 目标类
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T> T copy(Object objSource,Class<T> clazz) throws InstantiationException, IllegalAccessException{

		if(null == objSource) return null;//如果源对象为空,则直接返回null
		
		T objDes = clazz.newInstance();
		
		// 获得源对象所有属性
		Field[] fields = clazz.getDeclaredFields();
		
		// 循环遍历字段,获取字段对应的属性值  
		for ( Field field : fields )  
		{  
			// 如果不为空,设置可见性,然后返回  
			field.setAccessible( true );  
			
			try  
			{  
				field.set(objDes, field.get(objSource));
			}  
			catch ( Exception e )  
			{
            	logger.error("执行{}类的{}属性的set方法时出错。{}",clazz.getSimpleName(),field.getName(),e);
			}  
		}  
		return objDes;
	}
	
	/**
	 * 拷贝对象方法(适合不同类型的转换)<br/>
	 * 前提是,源类中的所有属性在目标类中都存在
	 * 
	 * @param objSource 源对象
	 * @param clazzSrc 源对象所属class
	 * @param clazzDes 目标class
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T, K> T copy(K objSource,Class<K> clazzSrc,Class<T> clazzDes ) throws InstantiationException, IllegalAccessException{
		
		if(null == objSource) return null;//如果源对象为空,则直接返回null
		
		T objDes = clazzDes.newInstance();
		
		return merge(objSource, objDes, clazzSrc, clazzDes);
		
	}
	
	
	/**
	 * 合并对象方法(适合不同类型的转换)<br/>
	 * 前提是,源类中的所有属性在目标类中都存在
	 * 
	 * @param objSource 源对象
	 * @param clazzSrc 源对象所属class
	 * @param clazzDes 目标class
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T, K> T merge(K objSource,T objDes,Class<K> clazzSrc,Class<T> clazzDes) throws InstantiationException, IllegalAccessException{
		return merge(objSource, objDes, clazzSrc,clazzDes, true);
	}
	
	/**
	 * 合并对象方法(适合不同类型的转换)<br/>
	 * 前提是,源类中的所有属性在目标类中都存在
	 * 
	 * @param objSource 源对象
	 * @param clazzSrc 源对象所属class
	 * @param clazzDes 目标class
	 * @param overwrite 是否覆盖已存在的属性值
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T, K> T merge(K objSource,T objDes,Class<K> clazzSrc,Class<T> clazzDes,boolean overwrite) throws InstantiationException, IllegalAccessException{
		return merge(objSource,  objDes, clazzSrc,clazzDes, overwrite,null);
	}
	
	/**
	 * 合并对象方法(适合不同类型的转换)<br/>
	 * 前提是,源类中的所有属性在目标类中都存在
	 * 
	 * @param objSource 源对象
	 * @param objDes 目标对象
	 * @param clazzSrc 源对象所属class
	 * @param clazzDes 目标class
	 * @param overwrite 是否覆盖已存在的属性值
	 * @param IgnoreMap 忽略的属性值
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T, K> T merge(K objSource,T objDes,Class<K> clazzSrc,Class<T> clazzDes,boolean overwrite,Set<String> IgnoreSet) throws InstantiationException, IllegalAccessException{
		
		if(null == objSource) return null;//如果源对象为空,则直接返回null

		//获取目标对象的所有属性
		Field[] fieldDeses = clazzDes.getDeclaredFields();
		Map<String,Field> m = new HashMap<String, Field>();
		// 循环遍历字段,获取字段对应的属性值  
		for ( Field field : fieldDeses )  
		{ 
			// 如果不为空,设置可见性,然后返回  
			field.setAccessible( true );  
			m.put(field.getName(), field);
		}
		
		
		// 获得源对象所有属性
		Field[] fields = clazzSrc.getDeclaredFields();
		// 循环遍历字段,获取字段对应的属性值  
		for ( Field field : fields )  
		{  
			//如果目标对象不存在该字段,则跳过
			if(!m.containsKey(field.getName())) continue;
			
			// 如果不为空,设置可见性,然后返回  
			field.setAccessible( true );  
			
			try  
			{  
				String fieldName = field.getName();// 属性名
				String firstLetter = fieldName.substring(0, 1).toUpperCase();// 获取属性首字母
				
				// 拼接set方法名
				String setMethodName = "set" + firstLetter + fieldName.substring(1);
				// 获取set方法对象
				Method setMethod = clazzDes.getMethod(setMethodName,new Class[]{field.getType()});

				//如果目标对象当前属性不为空
				if(null!=m.get(fieldName).get(objDes)){
					if(overwrite){//如果覆盖当前属性值,但map中存在,则不覆盖,否则覆盖
						if(null!=IgnoreSet && IgnoreSet.contains(fieldName.toUpperCase())){//如果map中有值
							continue;
						}
					}else{//如果不覆盖,但是map存在,则必须覆盖,否则不覆盖
						if(null==IgnoreSet || !IgnoreSet.contains(fieldName.toUpperCase())){//如果map中没有值
							continue;
						}
					}
				}
				// 对目标对象调用set方法装入属性值
				setMethod.invoke(objDes, field.get(objSource));
			}  
			catch ( Exception e )  
			{
				logger.error("执行{}类的{}属性的set方法时出错。{}",clazzDes.getSimpleName(),field.getName(),e);
			}  
		}  
		return objDes;
	}
	
	
}


通过反射克隆对象,对象复制(克隆),对象合并工具类 升级版

标签:

原文地址:http://blog.csdn.net/xiaoxian8023/article/details/43312929

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!