此代码参照《设计模式之禅》
不同过new关键字来创建对象,而是通过对象拷贝的方式来实现得到新的对象的模式就叫做原型模式。
注意:1.拷贝对象的时候,原来对象的构造函数不会被执行。
2.final修饰的变量不能进行拷贝。(final定义的变量不能被改变)
package com.designer.yuanxingmoshi.kaobei;
public class Client {
/**
* 浅拷贝
*
*/
public static void main(String[] args) {
//产生一个对象
Thing thing = new Thing();
//拷贝一个对象
Thing cloneThing = thing.clone(); //在arrayList还有存值的时候 先进行拷贝
//设置一个值
thing.setValue("张三");
cloneThing.setValue("李四");
//打印的 [张三, 李四] !!因为对象没有被拷贝所以用的同一个对象,所以值才没有改变
//进行深拷贝之后才会改变arrayList的值(只会打印李四)
System.out.println(thing.getValue());
System.out.println(cloneThing.getValue());
//打印数组的值
for (String str:cloneThing.aa)
{
System.out.println(str);
}
//怎么将对象进行深拷贝
cloneThing.adv.setAdvContext("ccvv"); //(是因为对象没有被拷贝(还是原来的对象,同一份值),所以打印的是同一个值。
System.out.println(thing.adv.getAdvContext());//ccvv
/**
* 拷贝后的对象,Java做了一个偷懒的拷贝动作
* 只是做了一个浅拷贝,其对象内部数组、引用的对象不会被拷贝,
* 还是指向原生对象的内部元素地址,
* 还是应用同一份,所以原对象和拷贝的对象的里面的引用对象的值还是一样的。
* 只有原始类型的的值,比如int,long,String(Java就希望你把String认为是基本类型,String是没有clone方法的)才会被拷贝,重新复制一份。
*
*/
System.out.println(thing.bb); //原对象 bb
System.out.println(cloneThing.bb); //拷贝后的对象 bb
cloneThing.bb="BB";
System.out.println(thing.bb); // bb
System.out.println(cloneThing.bb); //BB
/**
* 测试方法类的对象是否会拷贝
*/
thing.testjubu().setAdvContext("mm");
System.out.println(thing.testjubu().getAdvContext()); //原对象 bb
System.out.println(cloneThing.testjubu().getAdvContext()); //原对象 bb
}
}
package com.designer.yuanxingmoshi.kaobei;
import java.util.ArrayList;
import com.designer.yuanxingmoshi.AdvTemplate;
public class Thing extends Object implements Cloneable
{
//定义一个私有变量
private ArrayList<String> arrayList = new ArrayList<String>();
public String values;
public String aa[]={"a","b"};
public AdvTemplate adv = new AdvTemplate();
public String bb="bb";
@SuppressWarnings("unchecked")
@Override
public Thing clone()
{
Thing thing = null;
try
{
thing = (Thing)super.clone();
//深拷贝 自己将不是原有类型的值(基本类型的值) 对象数组自己手动进行拷贝,称为深拷贝;
thing.arrayList=(ArrayList<String>)this.arrayList.clone();
// this.adv=(AdvTemplate)adv.clone();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return thing;
}
//设置HashMap的值
public void setValue(String value)
{
this.arrayList.add(value);
}
//取得arrayList的值
public ArrayList<String> getValue()
{
return this.arrayList;
}
public void setValues(String values)
{
this.values = values;
}
public String getValues()
{
return values;
}
/**
* <一句话功能简述>
* <功能详细描述>
* @see [类、类#方法、类#成员]
* 满足两个条件的对象才不会被拷贝:一是类的成员变量,而不是方法内的变量;二是必须是一个对象,而不是一个原始类型
*
* 测试方法内的,局部的对象是否会拷贝(预期会拷贝) XX测试不成功
*/
public static AdvTemplate testjubu()
{
AdvTemplate adv = new AdvTemplate();
adv.setAdvContext("jubu");
return adv;
}
}