Java的深度克隆和浅度克隆
说到克隆,其实是个比较简单的概念,跟现实生活正的克隆一样,复制一个一模一样的对象出来。clone()这个方法是从Object继承下来的,一个对象要实现克隆,需要实现一个叫做Cloneable的接口,这个接口没有什么方法,和Comparable接口差不多,仅仅是起一个标志作用,实现了这个接口你就能实现克隆操作。
这里有两个概念,深度克隆和浅度克隆,这东西虽然平常不怎么用,但是了解一下还是有必要的。Object中的克隆方法是浅度克隆,JDK规定了克隆需要满足的一些条件,简要总结一下就是:对某个对象进行克隆,对象的的成员变量如果包括引用类型或者数组,那么克隆的时候其实是不会把这些对象也带着复制到克隆出来的对象里面的,只是复制一个引用,这个引用指向被克隆对象的成员对象,但是基本数据类型是会跟着被带到克隆对象里面去的。而深度可能就是把对象的所有属性都统统复制一份新的到目标对象里面去。简单画个图:
写了几行代码测试一下:(针对数组,对象其实跟数组是一样的)
1 class Person implements Cloneable { 2 String name; 3 String password; 4 String[] arrFavor; 5 6 public Person(String name, String password, String[] arrFavor) { 7 this.name = name; 8 this.password = password; 9 this.arrFavor = arrFavor; 10 } 11 12 @Override 13 protected Object clone() { 14 Person person = null; 15 try { 16 person = (Person) super.clone(); 17 // person.arrFavor = arrFavor.clone(); 18 return person; 19 } catch (CloneNotSupportedException e) { 20 e.printStackTrace(); 21 } 22 return null; 23 } 24 } 25 26 public class Test4 { 27 public static void main(String[] args) { 28 String[] arrFavor = { "basketball", "football" }; 29 Person person = new Person("Jay", "123", arrFavor); 30 Person p = (Person) person.clone(); 31 System.out.println(p.name); 32 System.out.println(p.password); 33 p.name = "Jolin"; 34 p.password = "555"; 35 p.arrFavor[0] = "valiball"; 36 for (String favor : p.arrFavor) { 37 System.out.print(favor + " "); 38 } 39 System.out.println(); 40 for (String favor : person.arrFavor) { 41 System.out.print(favor + " "); 42 } 43 System.out.println(); 44 } 45 } 46 // 结果 47 // Jay 48 // 123 49 // valiball football 50 // valiball football
而如果要进行所谓的深度克隆,在重写clone方法的时候把属性也克隆一下,也就是上面代码的去掉17行注释。