浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
2.1 浅克隆
看下面一个例子
public class Test {
public static void main(String[] args) CloneCar {
Car car = new Car();
car.name = "MB";
Car car1;
car1 = car;
System.out.println(car == car1);
car1.name = "BMW";
System.out.println("car: " + car.name + " car1: " + car1.name);
car1 = (Car) car.clone();
System.out.println(car == car1);
car1.name = "BMW";
System.out.println("car: " + car.name + " car1: " + car1.name);
}
}
class Car implements Cloneable{
String name;
@Override
protected Object clone() CloneCar {
return super.clone();
}
}
结果:
trye
car: MB car1: MB
false
car: MB car: BMW
Car类实现了Cloneable接口,并且重写了clone方法。
首先设car1变量值等于car,car1直接指向car的地址,两个地址相同,所以测试car1==car时,结果为true,car1的name值为“MB”,car的name值也改为“MB”。
car.clone(),将car的值克隆给car1,这时car1的指向stu对象副本的地址,地址发生改变,测试car1==car,结果为false。改变car1的name值为"BMW",两者因为指向的对象不同,car的name值并未改变。
2.2 深克隆
Car类包含tyre类,这时再使用clone方法。
public class Test {
public static void main(String[] args) CloneCar {
Car car = new Car();
car.name = "BMW";
car.tyre.name = "tyreA";
Car car1;
car1 = (Car) car.clone();
System.out.println(car1.tyre == car.tyre);
car1.tyre.name = "tyreB";
System.out.println("car1: " + car1.tyre.name + " car: " + car.tyre.name);
}
}
class Car implements Cloneable{
String name;
Tyre tyre = new Tyre();
@Override
protected Object clone() CloneCar {
return super.clone();
}
}
class Tyre{
String name;
}
结果:
true
car: tyreB car: tyreB
运用深克隆之后,对于引用类型,clone方法只克隆引用类型的地址。此时car1.tyre的地址与car.tyre的地址相同,改变car1.tyre.name的值后,car.tyre.name的值也发生了相应的改变。
总结:
浅拷贝是克隆对象的方法,在这种方法中,旧对象的值被复制到新对象中。在复制对象值时,即对象的地址将指向克隆对象的地址。因此,对克隆对象或新对象所做的任何更改都会反映到其他对象中。
如果我们想创建原对象的一个深拷贝并创建一个新对象,将值放入其中,这意味着克隆对象或新对象中的值所做的任何更改,只会反映在该被更改对象中,而不反映在另一个中。