zoukankan      html  css  js  c++  java
  • java 浅复制和深复制的实现

    public class Thing implements Cloneable{  
        //定义一个私有变量  
        private ArrayList<String> arrayList = new ArrayList<String>();  
     
        @Override  
        public Thing clone(){  
            Thing thing=null;  
            try {  
                thing = (Thing)super.clone();  
            } catch (CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            return thing;  
        }  
        //设置HashMap的值  
        public void setValue(String value){  
            this.arrayList.add(value);  
        }  
        //取得arrayList的值  
        public ArrayList<String> getValue(){  
            return this.arrayList;  
        }  
    } 

    在Thing类中增加一个私有变量arrayLis,类型为ArrayList,然后通过setValue和getValue分别进行设置和取值,我们来看场景类是如何拷贝的,如代码清单13-11所示。

    代码清13-11 浅拷贝测试

    public class Client {  
     
        public static void main(String[] args) {  
            //产生一个对象  
            Thing thing = new Thing();  
            //设置一个值  
            thing.setValue("张三");         
            //拷贝一个对象  
            Thing cloneThing = thing.clone();  
            cloneThing.setValue("李四");        
            System.out.println(thing.getValue());  
        }  
    } 

    结果会是什么?

    [张三, 李四] 

    为什么?

    怎么会这样呢?怎么会有李四呢?让我来给你解释,是因为Java做了一个偷懒的拷贝动作,Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝,确实是非常浅,两个对象共享了一个私有变量,你改我改大家都能改,是一种非常不安全的方式,在实际项目中使用还是比较少的(当然,这是也是一种"危机"环境的一种救命方式)。你可能会比较奇怪,为什么在Mail那个类中就可以使用String类型,而不会产生由浅拷贝带来的问题呢?内部的数组和引用对象才不拷贝,其他的原始类型比如int,long,String(Java就希望你把String认为是基本类型,String是没有clone方法的)等都会被拷贝的。

    注意  使用clone方法拷贝时,满足两个条件的对象才不会被拷贝:一是类的成员变量,而不是方法内的变量;二是必须是一个对象,而不是一个原始类型

    浅拷贝是有风险的,那怎么才能深入的拷贝呢?我们修改一下程序就可以深拷贝,如代码清单13-12所示。

    public class Thing implements Cloneable{  
        //定义一个私有变量  
        private ArrayList<String> arrayList = new 
    ArrayList<String>();  
     
        @Override  
        public Thing clone(){  
            Thing thing=null;  
            try {  
                thing = (Thing)super.clone();  
                thing.arrayList = (ArrayList<String>)
    this.arrayList.clone();  
            } catch (CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            return thing;  
        }  
    } 

    仅仅增加了黑体部分,对私有的类变量进行独立的拷贝。Client类没有任何改变,运行结果如下所示。

    [张三] 

    该方法就实现了完全的拷贝,两个对象之间没有任何的瓜葛了,你修改你的,我修改我的,不相互影响,这种拷贝就叫做深拷贝,深拷贝还有一种实现方式就是通过自己写二进制流来操作对象,然后实现对象的深拷贝,这个大家有时间自己实现一下。

    注意  深拷贝和浅拷贝建议不要混合使用,特别是是在涉及到类的继承,父类有多个引用的情况就非常的复杂,建议的方案是深拷贝和浅拷贝分开实现。

  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/youxin/p/2950206.html
Copyright © 2011-2022 走看看