欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

getM.invoke(src)); } } CAD加密 return des ;} 没有那么多验证

点击: 次  来源:宝鼎软件 时间:2017-08-16

原文出处: Hosee

在Java开拓事情中,有许多时候我们需要将差异的两个工具实例举办属性复制,从而基于源工具的属性信息举办后续操纵,软件开发,而不改变源工具的属性信息。这两个工具实例有大概是同一个类的两个实例,劳务派遣管理系统,也大概是差异类的两个实例,可是他们的属相名称沟通。譬喻DO、DTO、VO、DAO等,这些实体的意义请查察DDD中分层架构。本文主要先容几种工具拷贝的要领

1. 工具拷贝

工具拷贝分为深拷贝和浅拷贝。按照利用场景举办差异选择。在Java中,数据范例分为值范例(根基数据范例)和引用范例,值范例包罗int、double、byte、boolean、char等简朴数据范例,引用范例包罗类、接口、数组等巨大范例。

深度拷贝和浅度拷贝的主要区别在于是否支持引用范例的属性拷贝,本文将探讨今朝利用较多的几种工具拷贝的方案,以及其是否支持深拷贝和机能比拟。

2. BeanUtils

2.1 apache的BeanUtils方案

利用org.apache.commons.beanutils.BeanUtils举办工具深入复制时候,主要通过向BeanUtils框架注入新的范例转换器,因为默认环境下,BeanUtils对巨大工具的复制是引用,譬喻:

public static void beanUtilsTest() throws Exception {
    // 注册转化器
    BeanUtilsBean.getInstance().getConvertUtils().register(new ArbitrationConvert(), ArbitrationDO.class);
    Wrapper wrapper = new Wrapper();
    wrapper.setName("copy");
    wrapper.setNameDesc("copy complex object!");
    wrapper.setArbitration(newArbitrationDO());
    Wrapper dest = new Wrapper();
    // 工具复制
    BeanUtils.copyProperties(dest, wrapper);
    // 属性验证
    wrapper.getArbitration().setBizId("1");
    System.out.println(wrapper.getArbitration() == dest.getArbitration());
    System.out.println(wrapper.getArbitration().getBizId().equals(dest.getArbitration().getBizId()));
}

public class ArbitrationConvert implements Converter {

    @Override
    public <T> T convert(Class<T> type, Object value) {
        if (ArbitrationDO.class.equals(type)) {
            try {
                return type.cast(BeanUtils.cloneBean(value));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

可以发明,利用org.apache.commons.beanutils.BeanUtils复制引用时,主和源的引用为同一个,即改变了主的引用属性会影响到源的引用,所以这是一种浅拷贝。

需要留意的是,apache的BeanUtils中,以下范例假如为空,会报错(org.apache.commons.beanutils.ConversionException: No value specified for *)

/**
     * Register the converters for other types.
     * </p>
     * This method registers the following converters:
     * <ul>
     *     <li>Class.class - {@link ClassConverter}
     *     <li>java.util.Date.class - {@link DateConverter}
     *     <li>java.util.Calendar.class - {@link CalendarConverter}
     *     <li>File.class - {@link FileConverter}
     *     <li>java.sql.Date.class - {@link SqlDateConverter}
     *     <li>java.sql.Time.class - {@link SqlTimeConverter}
     *     <li>java.sql.Timestamp.class - {@link SqlTimestampConverter}
     *     <li>URL.class - {@link URLConverter}
     * </ul>
     * @param throwException <code>true if the converters should
     * throw an exception when a conversion error occurs, otherwise <code>
     * <code>false if a default value should be used.
     */
    private void registerOther(boolean throwException) {
        register(Class.class,         throwException ? new ClassConverter()        : new ClassConverter(null));
        register(java.util.Date.class, throwException ? new DateConverter()        : new DateConverter(null));
        register(Calendar.class,      throwException ? new CalendarConverter()     : new CalendarConverter(null));
        register(File.class,          throwException ? new FileConverter()         : new FileConverter(null));
        register(java.sql.Date.class, throwException ? new SqlDateConverter()      : new SqlDateConverter(null));
        register(java.sql.Time.class, throwException ? new SqlTimeConverter()      : new SqlTimeConverter(null));
        register(Timestamp.class,     throwException ? new SqlTimestampConverter() : new SqlTimestampConverter(null));
        register(URL.class,           throwException ? new URLConverter()          : new URLConverter(null));
    }

当碰着这种问题是,可以手动将范例转换器注册进去,好比data范例:

public class BeanUtilEx extends BeanUtils { 

private static Map cache = new HashMap(); 
private static Log logger = LogFactory.getFactory().getInstance(BeanUtilEx.class); 

private BeanUtilEx() { 
} 

static { 
// 注册sql.date的转换器,即答允BeanUtils.copyProperties时的源方针的sql范例的值答允为空 
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class); 
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class);  
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class); 
// 注册util.date的转换器,即答允BeanUtils.copyProperties时的源方针的util范例的值答允为空 
} 

public static void copyProperties(Object target, Object source) 
throws InvocationTargetException, IllegalAccessException { 
// 支持对日期copy 
org.apache.commons.beanutils.BeanUtils.copyProperties(target, source); 

}

2.2 apache的PropertyUtils方案