所谓简单克隆也就是浅拷贝,即它只会拷贝对象中的基本数据类型的数据(比如,int、long),以及引用对象(比如 List)的内存地址,不会递归地拷贝引用对象本身。
PS:在 Java 语言中,Object 类的 clone() 方法执行的就是浅拷贝。
下面,我们还是通过示例来演示一下,如何实现基于浅拷贝的原型模式…
具体示例
一个标准的原型模式代码,应该是这样设计的。先创建原型 Prototype 接口:
public interface Prototype{
Prototype clone();
}
创建具体需要克隆的对象 ConcretePrototypA:
public class ConcretePrototypeA implements Prototype {
private int age;
private String name;
private List hobbies;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getHobbies() {
return hobbies;
}
public void setHobbies(List hobbies) {
this.hobbies = hobbies;
}
@Override
// 拷贝的逻辑
public ConcretePrototypeA clone() {
// 创建一个新对象
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
// 直接将当前对象的值填充,不做任何多余处理
concretePrototype.setAge(this.age);
concretePrototype.setName(this.name);
concretePrototype.setHobbies(this.hobbies);
return concretePrototype;
}
}
创建 Client 对象:
public class Client {
private Prototype prototype;
public Client(Prototype prototype){
this.prototype = prototype;
}
public Prototype startClone(Prototype concretePrototype){
return (Prototype)concretePrototype.clone();
}
}
测试代码:
public class PrototypeTest {
public static void main(String[] args) {
// 创建一个具体的需要克隆的对象
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
// 填充属性,方便测试
concretePrototype.setAge(18);
concretePrototype.setName("prototype");
List hobbies = new ArrayList<String>();
concretePrototype.setHobbies(hobbies);
// 打印原对象地址
System.out.println(concretePrototype);
// 创建Client对象,准备开始克隆
Client client = new Client(concretePrototype);
ConcretePrototypeA concretePrototypeClone = (ConcretePrototypeA) client.startClone(concretePrototype);
// 打印新对象地址
System.out.println(concretePrototypeClone);
// 比较两个对象的引用类型成员变量
System.out.println("克隆对象中的引用类型地址值:" + concretePrototypeClone.getHobbies());
System.out.println("原对象中的引用类型地址值:" + concretePrototype.getHobbies());
System.out.println("对象地址比较:"+(concretePrototypeClone.getHobbies() == concretePrototype.getHobbies()));
}
}
运行结果如下:

从中可以看到,拷贝得到的对象是一个新对象,与原对象不同;另外,这个新对象的引用类型成员变量 hobbies,与原对象的 hobbies 的地址相同;这意味着复制的不是值,而是引用的地址。这样的话,如果我们修改任一对象该属性的值 , concretePrototype 和 concretePrototypeCone 的 hobbies 值都会改变。
小结
这就是我们常说的浅克隆。只是完整复制了值类型数据,没有赋值引用对象。换言之,所有的引用对象仍然指向原来的对象,显然不是我们想要的结果。
下面我们来看深度克隆继续改造…
本文详细介绍了Java中的浅克隆和深克隆概念,通过示例代码展示了如何实现原型模式。浅克隆仅复制基本类型和引用对象的地址,而深克隆则递归复制所有引用对象。示例中展示了浅克隆导致的引用对象地址相同,进而影响到对象状态的问题。文章最后提到,为达到期望的完全独立的副本,需要采用深克隆技术。

被折叠的 条评论
为什么被折叠?



