public class CarCloneTest {
public static void main(String[] args) {
Brand brand = new Brand("BMW");
Car car = new Car(5, brand);
Car carClone;
carClone = (Car) car.clone(); //(1)
//carClone = (Car) car.deepClone(); //(2)
System.out.println("******************************************");
System.out.println("car "+car);
System.out.println("carClone "+carClone);
System.out.println("******************************************");
System.out.println("将car年限改为 7,品牌名称改为Banz");
brand.setName("Banz");
car.setYear(7);
System.out.println("******************************************");
System.out.println("car "+car);
System.out.println("carClone "+carClone);
}
}
浅克隆测试,运行(1)代码,得到结果如下:
******************************************
car [year=5, brand=Brand [name=BMW]]
carClone [year=5, brand=Brand [name=BMW]]
******************************************
将car年限改为 7,品牌名称改为Banz
******************************************
car [year=7, brand=Brand [name=Banz]]
carClone [year=5, brand=Brand [name=Banz]]
可见当修改car中brand对象的名称为Banz时,carClone也跟着改变,可见其引用的brand对象为同一个,显然这不是我们想要的,而深克隆就解决了这个问题。
深克隆测试,运行(2)代码,得到结果如下:
******************************************
car [year=5, brand=Brand [name=BMW]]
carClone [year=5, brand=Brand [name=BMW]]
******************************************
将car年限改为 7,品牌名称改为Banz
******************************************
car [year=7, brand=Brand [name=Banz]]
carClone [year=5, brand=Brand [name=BMW]]
三、序列化实现深克隆
序列化对象必须实现Serializable接口,使对象可序列化。
public class Car implements Serializable{
private static final long serialVersionUID = 7883197573658810857L;
private int year; //使用年限
private Brand brand; //品牌
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public Brand getBrand() {
return brand;
}
public void setBrand(Brand brand) {
this.brand = brand;
}
public Car(int year, Brand brand) {
this.year = year;
this.brand = brand;
}
@Override
public String toString() {
return "[year=" + year + ", brand=" + brand + "]";
}
}
class Brand implements Serializable{
private static final long serialVersionUID = -6505899377489945908L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Brand(String name) {
this.name = name;
}
@Override
public String toString() {
return "Brand [name=" + name + "]";
}
}
克隆工具类 CloneUtil:
public final class CloneUtil {
private CloneUtil() { throw new AssertionError(); }
/**
* 序列化实现深克隆
* @param t 泛型对象
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T deepClone(T t) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut;
ObjectInputStream objIn;
T tClone = null ;
try {
objOut = new ObjectOutputStream(out);
objOut.writeObject(t); //将对象以二进制流形式写入
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
objIn = new ObjectInputStream(in);
tClone = (T)objIn.readObject(); //反序列化读取对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return tClone;
}
}
测试类 CarCloneTest: