原型模式
定义:不通过构造函数的new来创建对象的副本
需要:被克隆的对象实现Cloneable接口,并重写父类的clone()方法,如果没有实现,则抛出CloneNotSupportedException异常
分类: 克隆又分为 深拷贝和浅拷贝
注:String对象每次克隆都是新对象,这也是为什么推荐用StringBuffer的缘故
/**
* 原型模式-----对象克隆
*/
package Abstract.prototype;
class Person implements Cloneable
{
public int age;
public Person(int age)
{
this.age = age;
}
}
class Address implements Cloneable
{
public String address;
public Address(String address)
{
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Spoon implements Cloneable
{
public String name ;
public Person person;
public Address address;
@Override
protected Spoon clone()
{
Spoon obj = null;
try
{
obj = (Spoon)super.clone();
/**
* 如果想把对象Address、Person也克隆,需要加上这个
* 如果当前类所引用的Person Address里面没有对象,那么加上以后就是深克隆,
* 否则为伪深克隆,必须重写其内引用类的clone方法,以此类推
* 如果不写,那么就仅仅复制的Address的引用,如果Address引用的类属性变化,那么副本也会随之变化
*/
// obj.address = (Address) obj.address.clone();
}
catch (CloneNotSupportedException e)
{
System.out.println(" Object is not Cloneable ");
}
return obj;
}
}
public class Demo1 {
public static void main(String[] args) {
Spoon spoon = new Spoon();
spoon.person = new Person(18);
Spoon spoon1 = (Spoon)spoon.clone();
System.out.println(spoon); //Abstract.prototype.Spoon@1b6d3586
System.out.println(spoon1); //Abstract.prototype.Spoon@4554617c
System.out.println(spoon.person); //Abstract.prototype.Person@74a14482
System.out.println(spoon1.person); //Abstract.prototype.Person@74a14482
spoon.person.age = 38;
System.out.println("spoon:"+spoon.person.age);//38
System.out.println("spoon:"+spoon1.person.age);//38
}
}
如图,如果Spoon.clone()方法包含Address的克隆,那么其内存结构如图:
所以要想实现彻底的深拷贝是非常困难的。