日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )

發(fā)布時間:2025/6/17 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

        • I . 原型模式 總結(jié)
        • II . 原型模式 淺拷貝
        • III . 原型模式 深拷貝
        • IV . 原型模式 與 單例
        • V . 原型模式 中的 final 關(guān)鍵字 ( 禁止出現(xiàn) )



I . 原型模式 總結(jié)



1 . 原型模式本質(zhì)及性能 : 原型模式使用 clone 方法克隆對象 , 其本質(zhì)是在內(nèi)存中拷貝二進(jìn)制數(shù)據(jù) , 這種方式要比調(diào)用 new 構(gòu)造函數(shù)性能高得多 ;


2 . clone 核心是內(nèi)存拷貝 : clone 對象不使用復(fù)用原有對象 , 是在內(nèi)存中的另一個地址空間復(fù)制了一份一模一樣的數(shù)據(jù) , 然后將其首地址給新對象的引用 ;


3 . 原型模式適用場景 : ① 節(jié)省資源 ( 內(nèi)存 CPU 硬件等 ) , ② 構(gòu)造函數(shù)復(fù)雜 ( 計算繁瑣 耗時 ) , ③ 創(chuàng)建大量對象 ;


4 . 原型模式實(shí)現(xiàn) : 原型模式類實(shí)現(xiàn) Cloneable 接口 , 實(shí)現(xiàn)其中的 clone 方法 ;


① 淺拷貝實(shí)現(xiàn) : 淺拷貝默認(rèn)調(diào)用 super.clone ;

② 深拷貝實(shí)現(xiàn) : 深拷貝需要調(diào)用 每個引用成員對象的 clone 方法創(chuàng)建成員對象 , 然后賦值給新的原型模式創(chuàng)建的對象 , 作為其中的成員 ;


5 . 注意拷貝方式 : 默認(rèn)淺拷貝 , 如果類中有引用類型成員變量 , 需要考慮深拷貝問題 , 可能會出現(xiàn)多個對象持有同一個引用變量 ;



II . 原型模式 淺拷貝



1 . 淺拷貝 : 調(diào)用 clone 對象拷貝內(nèi)存中的數(shù)據(jù)時 , 要注意拷貝的是基礎(chǔ)數(shù)據(jù)類型 , 對于數(shù)組 , 集合 , 自定義類等引用數(shù)據(jù)類型僅拷貝地址 , 會造成所有的對象都持有同一個內(nèi)存地址的引用成員 ;


① 基礎(chǔ)數(shù)據(jù)類型 : 如果類中全部是基礎(chǔ)數(shù)據(jù)類型 , 使用 clone 可以將該類完整的復(fù)制一份 ;

② 引用數(shù)據(jù)類型 : 如果類中有引用類型成員 , 只是拷貝該成員的地址 , 所有的拷貝創(chuàng)建的原型模式實(shí)例對象都持有同一個引用 , 如果修改該引用成員的值 , 所有的原型對象實(shí)例的值都會跟著修改 ;


2 . 淺拷貝示例 :


① 原型模式類 Student : 該類中持有 Vector<String> courses 引用數(shù)據(jù)類型 , 調(diào)用 clone 方法在內(nèi)存中復(fù)制對象時 , 僅復(fù)制了對象的地址 , 即將該引用的地址賦值給了 clone 出的對象 ;

package kim.hsl.design.prototype.shallowcopy;import java.util.Vector;/*** 淺拷貝示例*/ public class Student implements Cloneable {private String name;private int age;//該類在拷貝時 , 如果使用淺拷貝 , 只是將地址拷貝走了 , 兩個對象實(shí)際上用的是同一個對象private Vector<String> courses = new Vector<>();public Student() {System.out.println("調(diào)用 Student 默認(rèn)構(gòu)造函數(shù)");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Vector<String> getCourses() {return courses;}public void setCourses(Vector<String> courses) {this.courses = courses;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", courses=" + courses +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {System.out.println("調(diào)用 Student clone 方法");return super.clone();} }

② 測試類 Main : 此處創(chuàng)建了兩個 Student 實(shí)例對象 , 但是兩個對象都持有同一個 Vector<String> courses 引用數(shù)據(jù)類型成員 , 當(dāng)修改其中一個成員時 , 兩個對象中的該成員都會改變 ;

package kim.hsl.design.prototype.shallowcopy;public class Main {public static void main(String[] args) {try {//測試使用 clone 方法實(shí)現(xiàn)的原型模式 , 使用原型模式創(chuàng)建 2 個對象Student newStudent = new Student();// 1 . 使用 clone 方法創(chuàng)建對象1Student student = (Student) newStudent.clone();student.setName("Tom");student.setAge(10);student.getCourses().add("數(shù)學(xué)");// 2 . 使用 clone 方法創(chuàng)建對象2Student student2 = (Student) newStudent.clone();student2.setName("Jerry");student2.setAge(18);student2.getCourses().add("語文");System.out.println("student : " + student + "\nstudent2 : " + student2);} catch (CloneNotSupportedException e) {//捕獲 clone 方法可能產(chǎn)生的異常e.printStackTrace();}} }

③ 執(zhí)行結(jié)果 : 調(diào)用第一個對象 add 方法 , 在 vector 集合中添加了 “數(shù)學(xué)” 字符串 , 調(diào)用第二個對象的 add 方法 , 向 courses 集合中添加 “語文” 字符串 , 理論上兩個分別是 “數(shù)學(xué)” 和 “語文” , 但是此處卻都變成了 “數(shù)學(xué)” “語文” 兩個課程 , 說明兩個原型模式對象持有的 Vector<String> courses 變量是指向同一個內(nèi)存地址的 ;

調(diào)用 Student 默認(rèn)構(gòu)造函數(shù) 調(diào)用 Student clone 方法 調(diào)用 Student clone 方法 student : Student{name='Tom', age=10, courses=[數(shù)學(xué), 語文]} student2 : Student{name='Jerry', age=18, courses=[數(shù)學(xué), 語文]}

III . 原型模式 深拷貝



1 . 深拷貝策略 : 深拷貝時需要在 clone 方法中 , 調(diào)用引用數(shù)據(jù)類型本身的 clone 對象 , 在將其賦值給被拷貝的原型模式實(shí)例對象 ;


2 . 深拷貝 clone 方法流程 :


① 創(chuàng)建實(shí)例對象 : 通過 clone 方法 , 創(chuàng)建原型模式類的實(shí)例對象 , 此時該對象的引用成員處于淺拷貝狀態(tài) ;

② 拷貝引用成員 : 調(diào)用原型模式類對象成員的 clone 對象 , 創(chuàng)建新的成員對象 , 將新的成員對象賦值給克隆出的原型模式對象 ;

③ 返回新的對象 : 返回 clone 創(chuàng)建的原型模式實(shí)例對象 ;


3 . 示例代碼 :


① 原型模式深拷貝示例 : 深拷貝與淺拷貝只是在 clone 方法中表現(xiàn)不同 , 其它代碼一致 ; 在 clone 方法中需要針對引用類型進(jìn)行克隆 ;

package kim.hsl.design.prototype.deepcopy;import java.util.Vector;/*** 淺拷貝示例*/ public class Student implements Cloneable {private String name;private int age;//該類在拷貝時 , 如果使用淺拷貝 , 只是將地址拷貝走了 , 兩個對象實(shí)際上用的是同一個對象private Vector<String> courses = new Vector<>();public Student() {System.out.println("調(diào)用 Student 默認(rèn)構(gòu)造函數(shù)");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Vector<String> getCourses() {return courses;}public void setCourses(Vector<String> course) {this.courses = course;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", course=" + courses +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {System.out.println("調(diào)用 Student clone 方法");//1 . 首先拷貝一個基本對象Student student = (Student) super.clone();//2 . 將引用類型的對象單獨(dú)克隆賦值student.courses = (Vector<String>) this.courses.clone();//3 . 返回創(chuàng)建的新的對象return student;} }

② 測試代碼 :

package kim.hsl.design.prototype.deepcopy;public class Main {public static void main(String[] args) {try {//測試使用 clone 方法實(shí)現(xiàn)的原型模式 , 使用原型模式創(chuàng)建 2 個對象Student newStudent = new Student();// 1 . 使用 clone 方法創(chuàng)建對象1Student student = (Student) newStudent.clone();student.setName("Tom");student.setAge(10);student.getCourses().add("數(shù)學(xué)");// 2 . 使用 clone 方法創(chuàng)建對象2Student student2 = (Student) newStudent.clone();student2.setName("Jerry");student2.setAge(18);student2.getCourses().add("語文");System.out.println("student : " + student + "\nstudent2 : " + student2);} catch (CloneNotSupportedException e) {//捕獲 clone 方法可能產(chǎn)生的異常e.printStackTrace();}} }

③ 運(yùn)行結(jié)果 : 原型模式的兩個實(shí)例對象的互不干擾 ;


調(diào)用 Student 默認(rèn)構(gòu)造函數(shù) 調(diào)用 Student clone 方法 調(diào)用 Student clone 方法 student : Student{name='Tom', age=10, course=[數(shù)學(xué)]} student2 : Student{name='Jerry', age=18, course=[語文]}

IV . 原型模式 與 單例



1 . 原型模式 與 單例模式 :


① 原型模式 : 原型模式的核心是不調(diào)用構(gòu)造函數(shù) , 使用 clone 方法在內(nèi)存中克隆對象 ;

② 單例模式 : 單例模式的核心是私有化構(gòu)造函數(shù) , 控制外部用戶 , 不能隨意調(diào)用構(gòu)造函數(shù)創(chuàng)建對象 ;


2 . Cloneable 破壞了單例模式 : 此處二者就出現(xiàn)了矛盾 , 如果單例類 , 實(shí)現(xiàn)了 Cloneable 接口 , 那么該類就可以調(diào)用 clone 方法創(chuàng)建另外的實(shí)例對象 , 因此破壞了單例模式 ;


3 . 解決方案 :

① 不實(shí)現(xiàn) Cloneable 接口 : 單例模式中不要實(shí)現(xiàn) Cloneable 接口 , 不提供內(nèi)存拷貝功能 ;

② clone 中調(diào)用單例 : 如果必須實(shí)現(xiàn) Cloneable 接口 , 那么在重寫的 clone 方法中 , 調(diào)用獲取單例類的方法 , 不要進(jìn)行內(nèi)存對象拷貝創(chuàng)建新的實(shí)例對象 ;



V . 原型模式 中的 final 關(guān)鍵字 ( 禁止出現(xiàn) )



1 . final 作用 : final 用于修飾常量 , 被 final 修飾的變量無法重新賦值 ;


2 . Cloneable 實(shí)現(xiàn)類成員不要使用 final : 在原型模式的類中 , 實(shí)現(xiàn)了 Cloneable 接口 , 重寫了 clone 方法 , 其類對象的成員不能被 final 修飾 , 否則無法重新賦值 ;

總結(jié)

以上是生活随笔為你收集整理的【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。