原型模式 —— Java的賦值、淺克隆和深度克隆的區別

賦值 直接? = ,克隆 clone

假如說你想復制一個簡單變量。很簡單:

int a= 5;  
int b= a;  

b = 6;

這樣 a == 5, b == 6

不僅僅是int類型,其它七種原始數據類型(boolean,char,byte,short,float,double.long)同樣適用于該類情況。

但是如果你復制的是一個對象、list集合的情況下,情況就有些復雜了。

?

復制代碼
class Student {  private int number;  public int getNumber() {  return number;  }  public void setNumber(int number) {  this.number = number;  }  }  
public class Test {  public static void main(String args[]) {  Student stu1 = new Student();  stu1.setNumber(12345);  Student stu2 = stu1;  System.out.println("學生1:" + stu1.getNumber());  System.out.println("學生2:" + stu2.getNumber());  }  
}結果:學生1:12345  
學生2:12345  
復制代碼

?

這就怪了,為什么改變學生2的學號,學生1的學號也發生了變化呢?

原因出在(stu2 = stu1) 這一句。該語句的作用是將stu1的引用賦值給stu2,

這樣,stu1和stu2指向內存堆中同一個對象。如圖:

?

?

?

?

?

要做到 賦值的兩個對象之間的內存地址重新定義

實現對象克隆有兩種方式:

??1). 實現Cloneable接口并重寫Object類中的clone()方法;?

復制代碼
class Address implements Cloneable {  private String add;  public String getAdd() {  return add;  }  public void setAdd(String add) {  this.add = add;  }  @Override  public Object clone() {              // 下面 這個是重點Address addr = null;  try{  addr = (Address)super.clone();  }catch(CloneNotSupportedException e) {  e.printStackTrace();  }  return addr;  }  
}  
復制代碼

?

2). 實現Serializable接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆。

如果引用類型里面還包含很多引用類型,或者內層引用類型的類里面又包含引用類型,使用clone方法就會很麻煩。這時我們可以用序列化的方式來實現對象的深克隆。

復制代碼
public class Outer implements Serializable{private static final long serialVersionUID = 369285298572941L;  //最好是顯式聲明IDpublic Inner inner;//Discription:[深度復制方法,需要對象及對象所有的對象屬性都實現序列化] public Outer myclone() {Outer outer = null;try { // 將該對象序列化成流,因為寫在流里的是對象的一個拷貝,而原對象仍然存在于JVM里面。所以利用這個特性可以實現對象的深拷貝ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);// 將流序列化成對象ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);outer = (Outer) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return outer;}
}
復制代碼

?

?

實現對象克隆有兩種方式:

??1). 實現Cloneable接口并重寫Object類中的clone()方法;

??2). 實現Serializable接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆。

注意:基于序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優于使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來總是優于把問題留到運行時。

注: 集合的clone,ArrayList 默認實現了cloneable,但是List<A> A對象不是深度克隆,A對象的內容也是使用同一個內存地址,所以A對象也必須實現clone

?

?

轉載至:https://www.cnblogs.com/lemon-flm/p/9565695.html

轉載于:https://www.cnblogs.com/mh-study/p/10514010.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248373.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一個醫院院長電視機壞了,拿到一個大修理店去修

一個醫院院長電視機壞了&#xff0c;拿到一個大修理店去修。修理店接待人員:“OK&#xff0c;開機費50元”醫院院長: “為什么還沒修理就要先交費”&#xff1f;修理店接待人員: “我們修理店的制度就是這樣&#xff0c;你們醫院的掛號費&#xff0c;不是沒看病之前就要交嗎”&…

[scrum]2011/9/24-----第四天

scrum 總結&#xff1a; Team member Yesterday’s Work Today’s Work Issue R X Task201&#xff1a;Active Agenda Page的重寫&#xff0c;界面設置 Task201&#xff1a;Active Agenda Page 界面的美化&#xff0c;收縮折疊&#xff0c;并添加一些動畫效果 Task 243:…

c# 前后日期設置

List<string> list new List<string>(); //根據當月 顯示前6個月 for(int i0;i<6;i) { list.add(DateTime.Now.AddMonths(i*-1).Tostring()); }轉載于:https://www.cnblogs.com/Dcz1996/p/10515429.html

jq-AJAX 初步了解

js的異步操作(1) 定時器 (2) 事件 (3) 回調 (4) ajax Ajax優點 可以局部更新網頁內容。 ajax的本質就是xmlHttpRequest對象控制臺出現三個屬性 readyState 請求的五個階段 0 1 2 3 4 responseText 返回的文件內容 Status 狀態嗎 返回的狀態信息 在__proto__有三個方法 …

ARM學習筆記7——乘法指令

ARM乘法指令完成兩個數據的乘法&#xff0c;兩個32位二進制數相乘的結果是64位的4積。 其中&#xff1a; 1、“RadHi:RdLo”是由RdHi(最高有效32位)和RdLo(最低有效32位)鏈接形成的64位數&#xff0c;“[31:0]”只選取結果的最低有效32位 2、簡單的賦值由“&#xff1a;”表示…

《劍指offer》第四十三題(從1到n整數中1出現的次數)

// 面試題43&#xff1a;從1到n整數中1出現的次數 // 題目&#xff1a;輸入一個整數n&#xff0c;求從1到n這n個整數的十進制表示中1出現的次數。例如 // 輸入12&#xff0c;從1到12這些整數中包含1 的數字有1&#xff0c;10&#xff0c;11和12&#xff0c;1一共出現了5次。#in…

回調函數

又稱callback函數。意思是指&#xff1a;在你的程序中&#xff0c;被windows系統調用的函數。 這些函數雖然由你設計&#xff0c;但是永遠不會也不該被你調用&#xff0c;它們是為windows系統準備的。 窗口函數設計為callback形式&#xff0c;才能開放出一個接口給操作系統調用…

固態硬盤Ghost安裝Windows 10無法引導的問題

機器配置如下&#xff1a; 電腦型號 技嘉 B360M POWER 臺式電腦操作系統 Windows 10 64位 ( DirectX 12 )處理器 英特爾 Core i7-8700 3.20GHz 六核主板 技嘉 B360M POWER ( 英特爾 PCI 標準主機 CPU 橋 - CannonLake - A3…

Linux shell 內部命令與外部命令有什么區別以及怎么辨別

內部命令實際上是shell程序的一部分&#xff0c;其中包含的是一些比較簡單的linux系統命令&#xff0c;這些命令由shell程序識別并在shell程序內部完成運行&#xff0c;通常在linux系統加載運行時shell就被加載并駐留在系統內存中。內部命令是寫在bashy源碼里面的&#xff0c;其…

[轉]矩陣分解在推薦系統中的應用

矩陣分解是最近幾年比較火的算法&#xff0c;經過kddcup和netflix比賽的多人多次檢驗&#xff0c;矩陣分解可以帶來更好的結果&#xff0c;而且可以充分地考慮各種因素的影響&#xff0c;有非常好的擴展性&#xff0c;因為要考慮多種因素的綜合作用&#xff0c;往往需要構造cos…

iPhone 系統刷機

1. 下載好固件(愛思 或者 pp助手) e.g. http://jailbreak.25pp.com/gujian/ 2. 將電腦與手機連接上&#xff0c;彈出iTunes軟件即可 3. 長按手機電源鍵 關閉手機 4. 按住電源健&#xff0c;出現屏幕亮出現蘋果標志后再按住Home健 5. 屏幕黑屏時松開電源健&#xff0c;繼續按照H…

hdu4044

題意&#xff1a;給你一顆樹有n個節點&#xff0c;樹的根節點為1&#xff0c;表示為敵人的基地&#xff0c;其他葉子節點為你的基地&#xff0c;你一開始有m元&#xff0c;給你每個節點可以建造的塔的數量和塔的價格和可以照成的傷害&#xff0c;每個節點至多建立一座塔。敵人的…

RS100項目進展更新

1. 添加手機界面訪問網頁&#xff0c;畢竟PDA的屏幕大小和PC機大小不一致&#xff0c;完成了一自適應網頁&#xff0c;便于在手機上觀看實時畫面&#xff1b; 2. 此項目為一個遠程視頻監控遠程開關項目&#xff0c;遠程PC機或者手機能操作到監控端的開關&#xff0c;所以在遠程…

python os操作

1 # 常用的文件管理操作2 # https://www.cnblogs.com/dkblog/archive/2011/03/25/1995537.html3 import os4 import shutil5 6 # 切換工作目錄,默認是在當前目錄下7 # os.chdir("xx")8 9 # 當前的工作目錄 D:\pythonworkspace\py_base\cn\tele\io 10 print(os.getcw…

洛谷模板,樹狀數組二 差分

題目鏈接&#xff1a;https://www.luogu.org/problemnew/show/P3368 先介紹下差分&#xff1a; 設數組a[]{1,6,8,5,10}&#xff0c;那么差分數組b[]{1,5,2,-3,5} 也就是說b[i]a[i]-a[i-1];(a[0]0;)&#xff0c;那么a[i]b[1]....b[i];(這個很好證的)。 假如區間[2,4]都加上2的話…

KMS安裝后激活機器

slmgr /skms 192.168.26.82 slmgr /ato轉載于:https://www.cnblogs.com/EllieSoft/p/3410320.html

Java內存模型深度解析:總結

處理器內存模型 順序一致性內存模型是一個理論參考模型&#xff0c;JMM和處理器內存模型在設計時通常會把順序一致性內存模型作為參照。JMM和處理器內存模型在設計時會對順序一致性模型做一些放松&#xff0c;因為如果完全按照順序一致性模型來實現處理器和JMM&#xff0c;那么…

sourcetree,創建工作流報錯:Fatal: Not a gitflow-enabled repo yet. Please run 'git flow init' first.-》解決辦法...

1、打開項目下.git/config文件&#xff0c;或者如下圖操作&#xff1a; 2、打開config文件以后&#xff0c;刪除所有 [gitflow *條目并保存文件 3、關閉并重新打開sourcetree 4、倉庫-》Git 工作流-》初始化倉庫即可轉載于:https://www.cnblogs.com/yxfeng/p/10536955.html

關于a標簽的href屬性的注意事項

今天在做一個lightbox效果的時候出現了一個問題。 當往下滾動再點擊按鈕出現lightbox的時候&#xff0c;lightbox的遮罩層不能鋪滿&#xff08;即滾動高度處不能鋪上&#xff09;&#xff0c;如下圖所示。原因是提交按鈕使用的是a標簽&#xff0c;當給a標簽寫上href屬性的時候&…

爬蟲開發4.三種數據解析方式

數據解析三種方式引言&#xff1a;回顧requests實現數據爬取的流程 指定url基于requests模塊發起請求獲取響應對象中的數據進行持久化存儲其實&#xff0c;在上述流程中還需要較為重要的一步&#xff0c;就是在持久化存儲之前需要進行指定數據解析。因為大多數情況下的需求&…