Java中的深克隆和浅克隆(Clone)
浅克隆(shallow clone)和深克隆(deep clone)是两种不同的对象复制方法。
浅克隆会创建一个新对象,然后将原始对象的所有字段复制到新对象中。如果字段是基本类型,则它们的值将被直接复制。如果字段是引用类型,则只会复制引用,而不会复制引用指向的对象。这意味着原始对象和克隆对象中的引用类型字段将指向同一个对象。
深克隆不仅会复制原始对象的所有字段,还会递归地复制引用类型字段指向的所有对象。这意味着原始对象和克隆对象中的引用类型字段将指向不同的对象。
在Java中,要实现对象的浅克隆和深克隆,可以让你的类实现Cloneable
接口,并重写Object
类中的clone
方法。
浅克隆可以通过调用super.clone()
方法来实现。这将创建一个新对象,并将原始对象的所有字段复制到新对象中。如果字段是基本类型,则它们的值将被直接复制。如果字段是引用类型,则只会复制引用,而不会复制引用指向的对象。
深克隆需要手动实现。需要在clone
方法中创建一个新对象,并递归地复制所有引用类型字段指向的对象。
下面是一个示例类,它演示了如何实现浅克隆和深克隆:
1 public class MyClass implements Cloneable { 2 private int x; 3 private int[] y; 4 5 public MyClass(int x, int[] y) { 6 this.x = x; 7 this.y = y; 8 } 9 10 public int getX() { 11 return x; 12 } 13 14 public int[] getY() { 15 return y; 16 } 17 18 @Override 19 public MyClass clone() throws CloneNotSupportedException { 20 MyClass clone = (MyClass) super.clone(); 21 // Deep clone the y array 22 clone.y = y.clone(); 23 return clone; 24 } 25 }
在这个示例中,我们定义了一个名为MyClass
的类,它包含两个字段:一个整型字段x
和一个整型数组字段y
。我们让这个类实现了Cloneable
接口,并重写了clone
方法。
在clone
方法中,我们首先调用了super.clone()
方法来执行浅克隆。然后,我们对整型数组字段y
执行了深克隆,即通过调用它的clone
方法来创建一个新的数组。
要使用这个类来创建浅克隆和深克隆对象,可以这样写:
int[] y = {1, 2, 3}; MyClass original = new MyClass(10, y); MyClass shallowClone = original.clone(); MyClass deepClone = original.clone(); System.out.println("Original: " + original.getX() + ", " + Arrays.toString(original.getY())); System.out.println("Shallow clone: " + shallowClone.getX() + ", " + Arrays.toString(shallowClone.getY())); System.out.println("Deep clone: " + deepClone.getX() + ", " + Arrays.toString(deepClone.getY())); y[0] = 100; System.out.println("After modifying the original object:"); System.out.println("Original: " + original.getX() + ", " + Arrays.toString(original.getY())); System.out.println("Shallow clone: " + shallowClone.getX() + ", " + Arrays.toString(shallowClone.getY())); System.out.println("Deep clone: " + deepClone.getX() + ", " + Arrays.toString(deepClone.getY()));
在这个示例中,我们创建了一个原始对象original
,然后使用它的clone
方法创建了两个克隆对象:一个浅克隆对象和一个深克隆对象。接下来,我们修改了原始对象中的整型数组字段。
运行这段代码,将看到以下输出:
Original: 10, [1, 2, 3] Shallow clone: 10, [1, 2, 3] Deep clone: 10, [1, 2, 3] After modifying the original object: Original: 10, [100, 2, 3] Shallow clone: 10, [100, 2, 3] Deep clone: 10, [1, 2, 3]
从输出中可以看出,对原始对象的修改影响到了浅克隆对象,但没有影响到深克隆对象。