【java_設計模式】原型模式、淺拷貝和深拷貝
應用場景
須要同一個類的多個不一樣對象完成業務操做,羣發email,須要多個Mail類的對象
好處:提升性能
[Java] 純文本查看 複製代碼
?java
public static void main(String[] args) throws CloneNotSupportedException {設計模式
Mail mail = new Mail(); mail.setContent("初始化模板"); for(int i=0; i<10; i++) { //建立10個Mail的對象進行發郵件的操做,使用原型模式加快性能 Mail mailTemp = (Mail) mail.clone(); mailTemp.setName("第" + i + "個克隆出來的對象"); // 使用克隆採用的是二進制的拷貝,效率比直接new高不少 } // 不改變原來的Mail MailUtil.saveOriginMailRecord(mail);
}ide
實現
[Java] 純文本查看 複製代碼
?性能
// 省略get set方法
public class Mail implements Cloneable{.net
private String name; private String address; private String content; public Mail() { System.out.println("Mail Class Constructor"); } /** * 記得重寫方法 * @return * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Mail{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", content='" + content + '\'' + '}'; }
}設計
[Java] 純文本查看 複製代碼
?code
public class MailUtil {orm
public static void sendMail(Mail mail) { String outputContent = "向{0}同窗,郵件地址{1},郵件內容:{2},發送成功"; System.out.println(MessageFormat.format(outputContent, mail.getName(),mail.getAddress(),mail.getContent())); } public static void saveOriginMailRecord(Mail mail) { System.out.println("存儲originMail記錄,originMail:" + mail.getContent()); }
}對象
原理blog
原型模式的本質是類繼承Clonable接口,重寫clone方法。clone的底層是使用二進制拷貝,須要多個對象的時候能夠用該方法取代屢次new,提升性能。
坑
修改原對象的成員變量,可能會同時修改克隆出來的對象。避免這種坑即便用深拷貝。
不重寫clone方法,默認使用淺拷貝
[Java] 純文本查看 複製代碼
?
public class Pig implements Cloneable{
private String name; // 引用對象 private Date birthday; // 默認的clone方法,不會修改引用對象的指向,即拷貝出來的對象中birthday引用指向的是同一塊內存區域 @Override protected Object clone() throws CloneNotSupportedException { Pig pig = (Pig)super.clone(); // 深拷貝,有引用對象的時候須要重寫clone()方法 pig.birthday = (Date)pig.birthday.clone(); return pig; }
}
拓展
原型模式和單例模式結合的時候,注意修改clone方法
1.極端場景
[Java] 純文本查看 複製代碼
?
<font style="color:rgb(79, 79, 79)"><font face="""><font style="font-size:16px">// step 2克隆破壞單例
HungrySingleton hungrySingleton = HungrySingleton.getInstance(); Method method = hungrySingleton.getClass().getDeclaredMethod("clone"); method.setAccessible(true); HungrySingleton cloneHungrySingleton = (HungrySingleton) method.invoke(hungrySingleton); System.out.println(hungrySingleton); System.out.println(cloneHungrySingleton);
</font></font></font>
2.關鍵代碼
[Java] 純文本查看 複製代碼
?
<font style="color:rgb(79, 79, 79)"><font face="""><font style="font-size:16px"> /**
* 單例模式下使用的clone方法, 防止克隆破壞就要修改方法實現 * @return * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { return getInstance(); }</font></font></font>
做者:Ch.yang
來源:CSDN
原文:https://blog.csdn.net/chengha... 版權聲明:本文爲博主原創文章,轉載請附上博文連接!