一.克隆的概述:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
二.克隆的分类:
浅克隆:根据一个对象创建一个新的对象,新对象中的属性,方法名都一样。对于引用类型,新对象与原对象是同一个对象,即地址值指向相同。
深克隆:根据一个对象创建一个新的对象,新对象中的属性,方法名都一样。对于引用类型,新对象与原对象不是同一个对象,即地址值指向不同。
三.使用方式
1.浅克隆
jdk已经为我们封装好了相关方法,只需要继承Cloneable接口并实现其clone()方法就行。
例:一个蛋糕品牌上有很多信息,蛋糕名称,产地,品牌方,委托方等等。
但同一个品牌的不同蛋糕也就产品名称不同,其他可能都相同。如果每个名称都新建一个对象,那么就会很麻烦。此时就可以用浅克隆,克隆后再改一下产品名称就行。
代码实现:
/**
* 商品信息
*/
public class Goods implements Cloneable{
private String name;
//品牌
private String brand;
//产地
private String place;
//委托方
private principal principal;
public Goods(String name, String brand, String place, 浅克隆.principal principal) {
this.name = name;
this.brand = brand;
this.place = place;
this.principal = principal;
}
public void setName(String name) {
this.name = name;
}
public principal getPrincipal() {
return principal;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", brand='" + brand + '\'' +
", place='" + place + '\'' +
", principal=" + principal +
'}';
}
}
/**
* 委托方
*/
public class principal {
}
/**
* 测试(工厂类)
*/
public class MAIN {
public static void main(String[] args) throws CloneNotSupportedException {
Goods g1 = new Goods("抹茶蛋糕", "红跑车", "南京", new principal());
Goods g2 = (Goods)g1.clone();
g2.setName("巧克力蛋糕");
System.out.println(g1==g2);
System.out.println(g1);
System.out.println(g2);
}
}
测试结果:
通过结果可发现,浅克隆除了对象不同,内部属性都相同。
2.深克隆
深克隆可以通过反序列化来实现,或者自定义clone()方法。即其中的引用类型必须要重新new。
注意事项:需要反序列化的类必须要实现Serializable接口,否则会报异常。
代码实现:
/**
* 测试(工厂类)
*/
public class MAIN {
public static void main(String[] args) throws Exception {
Goods g1 = new Goods("抹茶蛋糕", "红跑车", "南京", new principal());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("object.txt"));
objectOutputStream.writeObject(g1);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("object.txt"));
Goods g2 = (Goods)objectInputStream.readObject();
g2.setName("巧克力蛋糕");
System.out.println(g1==g2);
System.out.println(g1);
System.out.println(g2);
}
}
结果:
这里通过文件流的形式进行反序列化,还可以通过转化成json字符串再转回object反序列化。通过结果可发现深克隆其引用类型不同。
总结:
克隆适用于对象的创建非常复杂,但有着相同属性的情况。能够降低复杂度。