日期:2014-05-20  浏览次数:20930 次

如何实现相同结构不同类的对象快速复制数据???
简单说就是class A和class B的结构一致,a为A的实例,b为B的实例,其中a有数据,我新建的b,想b得到和a一样的数据,如何快速实现?

------解决方案--------------------
commons-beanutils 包中的BeanUtils.copyProperties()属性拷贝
------解决方案--------------------
apache项目中有个beanUtil就是专门用于这方面的。你可以参见
http://commons.apache.org/beanutils/
------解决方案--------------------
Java code



import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.X.common.classtool.selector.BlankStringSelector;
import com.X.common.classtool.selector.FieldSelectorI;
import com.X.common.classtool.selector.NullSelector;

/**
 * 类复制工具
 * 2007-12-08
 */
public class ClassCopyUtils {

    private static final Logger log = Logger.getLogger(ClassCopyUtils.class);

    private List<FieldSelectorI> selectorList = new ArrayList<FieldSelectorI>(1);
    
    public ClassCopyUtils() {
        //默认选择非空的属性
        addSelector(new NullSelector(false));
    }
    
    public void copy(Object source, Object dest) {
        if (source == null || dest == null) {
            log.error("空值不能进行属性复制!");
            throw new RuntimeException("传入的要复制对象为空!");
        }
        String fieldOrignStr = null;
        String fieldName = null;
        Field destField = null;
        
        Method[] sourcrMethods = source.getClass().getDeclaredMethods();
        for (Method sourceMethod : sourcrMethods) {
            //必须是程序能正常访问到的属性 public Object getXXX()
            if (sourceMethod.getName().startsWith("get")&&Modifier.isPublic(sourceMethod.getModifiers())&&sourceMethod.getParameterTypes().length==0) {
                try {
                    Object value = sourceMethod.invoke(source, new Object[] {});
                    
                    boolean include = true;
                    for (FieldSelectorI selector : selectorList) {
                        if (!selector.include(value, null)) {
                            include = false;
                            break;
                        }
                    }
                    
                    if (include) {
                        try {
                            //如果是代理类只能用方法赋值
                            if (dest.getClass().getSimpleName().indexOf("$")!=-1) {
                                Method destMethod = null;
                                if (value instanceof Date) {
                                    try {
                                        destMethod = dest.getClass().getMethod(
                                                StringUtils.replaceOnce(sourceMethod.getName(), "get", "set"),
                                                value.getClass());
                                        destMethod.setAccessible(true);
                                        destMethod.invoke(dest, value);
                                    } catch (NoSuchMethodException e) {
                                        destMethod = dest.getClass().getMethod(
                                                StringUtils.replaceOnce(sourceMethod.getName(), "get", "set"),
                                                java.sql.Timestamp.class);
                                        destMethod.setAccessible(true);
                                        destMethod.invoke(dest, value);
                                    }
                                }else{
                                    destMethod = dest.getClass().getMethod(
                                            StringUtils.replaceOnce(sourceMethod.getName(), "get", "set"),
                                            value.getClass());
                                    destMethod.setAccessible(true);
                                    destMethod.invoke(dest, value);
                                }
                                log.debug("代理类方法"+destMethod.getName() + "成功");

                            } else {
                                fieldOrignStr = sourceMethod.getName().substring(3);
                                fieldName = fieldOrignStr.substring(0, 1).toLowerCase() + fieldOrignStr.substring(1);
                                destField = dest.getClass().getDeclaredField(fieldName);
                                destField.setAccessible(true);
                                destField.set(dest, value);
                                log.debug(fieldName + "赋值成功");
                            }
                        } catch (SecurityException e) {
                            log.info("方法"+StringUtils.replaceOnce(sourceMethod.getName(), "get", "set")+"导致一个安全异常:"+e.getMessage());
                        }
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    log.error("目标不具有访问性"+e.getMessage());
                } catch (InvocationTargetException e) {
                    log.error("方法调用出现异常:"+e.getMessage());
                } catch (NoSuchFieldException e) {
                    log.error("赋值出现异常,没有这个属性:"+fieldName);
                } catch (NoSuchMethodException e) {
                    log.error("方法调用出现异常:"+e.getMessage());
                }
            }
        }
    }
    
    public void includeBlankString(boolean include){
        addSelector(new BlankStringSelector(include));
    }

    public void addSelector(FieldSelectorI selector) {
        this.selectorList.add(selector);
    }

}