Jim Blog I've been trying so hard,but doesn't even matter
博客信息

Java 深浅克隆

发布时间:『 2018-05-05 17:16 』  博客类别:Java核心基础  阅读(104) 评论(0)

ArrayList源码分析中,我说ArrayList中的clone()方法是浅克隆(复制),所谓浅克隆,指的是虽然克隆出来的对象引用是不同的,但对象当中包含的对象的引用却是一样的。例如下面的代码:

ArrayList<Student> list=new ArrayList<>();
           list.add(new Student(1,"jim"));
           
           Object clone = list.clone(); //克隆出来的对象包含list中的内容
           System.out.println(clone==list); //false
          System.out.println(((ArrayList)clone).get(0)==list.get(0)); //true


深克隆,即克隆出来的对象引用不同,对象中包含的对象的引用也不同。如果要实现深克隆,只要要克隆的对象实现Cloneable接口就行了,在这个例子里,由于ArrayList自己实现了Cloneable接口,而我们的目的是ArrayList里的对象引用与原来不同,所以要在Student里也实现Cloneable接口,然后重写clone()方法:

@Override
               protected
Student clone(){
                              Student
student=null;
                              try
{
                                             student=(Student)
super.clone();
                              }
catch (CloneNotSupportedException e) {
                                             e.printStackTrace();
                              }
                              return
student;
               }


由于Student实现了clone()方法,所以当我们使用Student.clone()方法时将返回和原Student一样的属性却不是同一个引用的Studentps:我重写了toString()打印属性)

Student s=new Student(1, "jim");
           Student clone = s.clone();
           System.out.println(s);
           System.out.println(clone);
           System.out.println(s==clone); //false


最后的目标,深克隆ArrayList,代码如下:

ArrayList<Student> list=new ArrayList<>();
                              list.add(new
Student(1,"jim"));
                              
                              ArrayList<Student>
list2=new ArrayList<>(list.size());
                              Iterator<Student>
iterator = list.iterator();
                              while(iterator.hasNext()){
                                             list2.add(iterator.next().clone());
                              }
                              System.out.println(list.get(0)==list2.get(0));

由于浅克隆出来的ArrayList中已经包含了原ArrayList中的对象,所以实现深克隆应该是直接新建一个ArrayList,再在新的ArrayList中增加原ArrayList中的对象的克隆。即可实现ArrayList的引用不一样(很明显,因为后来的是新建的),而增加进去的对象是克隆的Student,即和原Student属性一样而引用不一样,这样即是深克隆了。

我个人也不太清楚克隆用得多不多,复制对象现在好像比较推荐用序列化的方式,好像应该写一篇关于序列化的文章。。。


关键字:   Java     clone     克隆  
博主信息
Jim
(生命,是一场徒劳的坚持)