zoukankan      html  css  js  c++  java
  • [编写高质量代码:改善java程序的151个建议]建议43 避免对象浅拷贝; 建议44:推荐使用序列化实现对象的深拷贝

    拷贝clone() 与new的区别?

     
    浅拷贝
    实现clone()方法的时候,
    如果用默认的super.clone()方法会调用Object类的默认拷贝,缺陷:不会把所有的属性全部拷贝一份,拷贝规则:
    (1)基本类型,拷贝其值
    (2)对象:
    拷贝引用地址,新拷贝的对象和原有对象共享该实例变量,不受访问权限控制。
    (3)String字符串:拷贝的是引用,但有点特殊,在修改时,会从字符串池中重新生成新的字符串。原有的字符串内容保持不变,故可以认为String是一个基本类型。
     
    为了实现深拷贝:
    在clone()方法的重载时,
    在设置属性时new一个对象出来。这样拷贝出来的和原来的不会共有一份引用。
     
    建议44.推荐使用序列化实现对象的深拷贝
     
    实现Cloneable接口实际上就具备了拷贝能力,但如果一个项目中有大量的对象是通过拷贝生成的,每个类都写一个clone(0方法,并且还要深拷贝?那就非常麻烦了。
    方法:
    通过序列化方式来处理,在内存中通过字节流的拷贝来实现,即把母体对象写到一个字节流中,再从字节流中将其读出来。该新对象和母对象之间不存在引用共享的问题,也就相当于深拷贝了一个新对象。
     
    public class ColoneUtils{
        public static <T extens Serializable> T clone(T obj){
            T cloneObj = null;
            try{
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(obj);
                oos.close();
                
                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);
                cloneObj = (T)ois.readObject();
                ois.close();
            }catch(Exception e){
                e.printStackTrace();
            }
            return cloneObj;
     
        }
    }
     
    当然,被拷贝的对象必须实现Serializeable接口,否则没办法拷贝的。
    还要注意:
    (1)对象的内部属性都是可序列化的
    (2)方法和属性的特殊修饰符。
    @transient
    瞬态变量,不进行序列化的变量。
     
    当然 Apache 的commons工具包中SerializationUtils类。没用过。
  • 相关阅读:
    NUMBER BASE CONVERSION(进制转换)
    2776 寻找代表元(匈牙利算法)
    最长严格上子序列(二分优化)
    c++ bitset类的使用和简介
    笨小猴 2008年NOIP全国联赛提高组
    三国游戏 2010年NOIP全国联赛普及组
    全国信息学奥林匹克联赛(NOIP2014)复赛 模拟题Day2 长乐一中
    codevs 1704 卡片游戏
    热浪
    全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中
  • 原文地址:https://www.cnblogs.com/akingseu/p/3485793.html
Copyright © 2011-2022 走看看