此代碼參照《設計模式之禪》
不同過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;
}
}