對象的克隆

對象的克隆

1、克隆即復制的意思,對象的克隆,意味著生成一個對象,這個對象和某個對象的屬性和行為是一致的,但是這個對象和源對象是兩個不同的對象。實現對象的克隆,方法是實現Cloneable接口,否則會報異常CloneNotSupportedException

 1 public class Demo implements Cloneable{
 2     private int number;
 3     private String name;
 4     
 5     public int getNumber() {
 6         return number;
 7     }
 8     public void setNumber(int number) {
 9         this.number = number;
10     }
11     public String getName() {
12         return name;
13     }
14     public void setName(String name) {
15         this.name = name;
16     }
17 
18 
19     public static void main(String[] args) {
20         Demo demo = new Demo();
21         Demo demo2 = null;
22         try {
23             demo2 = (Demo) demo.clone();
24             System.out.println(demo==demo2);
25             
26         } catch (CloneNotSupportedException e) {
27             e.printStackTrace();
28         }
29     }
30 }

輸出:

false

從結果我們可以知道,兩個引用指向的對象是兩個不同的Demo對象.

2、淺克隆

淺克隆是指在克隆對象的時候,對于對象中的屬性的值進行復制,那么這里引出一個問題,如對象的成員變量不論是基本類型還是引用類型,克隆對象的成員變量的值與源對象一致,這里引出一個問題,當成員變量是引用類型的時候,克隆對象和源對象的引用成員類型變量指向的是同一個對象,那么當這個對象本身的內容發生改動的時候,勢必影響到克隆對象和源對象,這樣在實際的生產過程可能帶來巨大問題。因此對象的克隆只在特定的場景下使用。

淺克隆的例子:

 1 public class Demo implements Cloneable{
 2     private int number;
 3     private Person person;
 4     public int getNumber() {
 5         return number;
 6     }
 7     public void setNumber(int number) {
 8         this.number = number;
 9     }
10     public Person getPerson() {
11         return person;
12     }
13     public void setPerson(Person person) {
14         this.person = person;
15     }
16     
17     public static void main(String[] args) {
18         Demo demo = new Demo();
19         demo.setNumber(10);
20         Person person = new Person();
21         person.setName("test");
22         demo.setPerson(person);
23         Demo demo2 = null;
24         try {
25             demo2 = (Demo) demo.clone();
26             //很明顯,源對象和克隆對象的引用類型變量指向同一個Person對象
27             System.out.println(demo.getPerson()==demo2.getPerson());
28             System.out.println(demo.getPerson().getName()+":"+demo2.getPerson().getName());
29             //person對象發生變動
30             person.setName("demo");
31             System.out.println(demo.getPerson().getName()+":"+demo2.getPerson().getName());
32             
33         } catch (CloneNotSupportedException e) {
34             e.printStackTrace();
35         }
36     }
37 }
38 
39 class Person{
40     private String name;
41 
42     public String getName() {
43         return name;
44     }
45     public void setName(String name) {
46         this.name = name;
47     }
48 }

輸出結果:

true
test:test
demo:demo

3、深克隆

在克隆時引用類型的變量在源對象和克隆對象中指向同一個對象。那么能否做到克隆出來的對象的引用屬性指向的對象與源對象是兩個不同的對象呢?答案是可以的,這種克隆被稱為深克隆。與淺克隆區別在于,復制對象的時候,是否對源對象中的引用變量指向的對象進行拷貝。進行深克隆的常用的手段是通過流和序列化/反序列化來實現。

 1 public class Demo implements Serializable{
 2     private int number;
 3     private Person person;
 4     public int getNumber() {
 5         return number;
 6     }
 7     public void setNumber(int number) {
 8         this.number = number;
 9     }
10     public Person getPerson() {
11         return person;
12     }
13     public void setPerson(Person person) {
14         this.person = person;
15     }
16     
17     public static void main(String[] args){
18         Demo demo = new Demo();
19         demo.setNumber(10);
20         Person person = new Person();
21         person.setName("test");
22         demo.setPerson(person);
23         Demo demo2 = ObjectUtil.clone(demo);
24         System.out.println(demo.getPerson()==demo2.getPerson());
25         System.out.println(demo.getPerson().getName()+":"+demo2.getPerson().getName());
26         //person對象發生變動
27         person.setName("demo");
28         System.out.println(demo.getPerson().getName()+":"+demo2.getPerson().getName());
29     }
30 }
31 
32 class Person implements Serializable{
33     private String name;
34 
35     public String getName() {
36         return name;
37     }
38     public void setName(String name) {
39         this.name = name;
40     }
41 }

工具類:

 1 public class ObjectUtil {
 2     @SuppressWarnings("unchecked")
 3     public static <T>T clone(T obj){
 4         T clonedObj = null;
 5         try {
 6             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 7             //將對象寫進字節流中
 8             ObjectOutputStream oos = new ObjectOutputStream(baos);
 9             oos.writeObject(obj);
10             //從字節流中讀出對象
11             ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
12             ObjectInputStream ois = new ObjectInputStream(bais);
13             clonedObj = (T)ois.readObject();
14         }catch (IOException e) {
15             e.printStackTrace();
16         }catch (ClassNotFoundException e) {
17             e.printStackTrace();
18         }
19         return clonedObj;
20     }
21 }

?

轉載于:https://www.cnblogs.com/liupiao/p/9254601.html

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

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

相關文章

15 調試

1. pdb pdb是基于命令行的調試工具&#xff0c;非常類似gnu的gdb&#xff08;調試c/c&#xff09;。 def getAverage(a,b):result abprint("result is %s"%result)return resulta 10 b 20 c ab ret getAverage(a,b) print(ret) 2.執行時調試 程序啟動&#xff0…

html5播放視頻只有聲音不出現畫面?

一開始網上大神們都是要把MP4的編碼格式轉換成AVC&#xff08;H264&#xff09;&#xff0c;然后趕緊用格式工廠把它給換了&#xff0c;結果&#xff01;&#xff01; 沒用&#xff01;&#xff01;還是黑屏&#xff1f;&#xff1f;&#xff1f;咋回事啊&#xff0c;然后自己又…

vue項目代碼改進(一)login組件

Login登錄組件 1. 新增登錄頭像&#xff08;css樣式回顧&#xff09; 1&#xff09;div.avatar 2&#xff09;子絕父相定位&#xff0c;left…top… 3&#xff09;border 4&#xff09;placeholder 5&#xff09;box-shadow box-shadow: offset-x offset-y blur spread color …

es6 --- set實現并集(Union)、交集(Intersect)和差集(Difference)

Set:類似于數組,但是成員的值都是唯一的 let a new Set([1, 2, 3]); let b new Set([4, 3, 2]);// 并集 let union new Set([...a, ...b]);// 交集 let intersect new Set([...a].filter(x > b.has(x)));// 差級 let difference new Set( [...a].filter(x > !b.has…

解析DBF文件

上周&#xff0c;公司給了許多DBF后綴的數據文件讓我進行解析。 因為是DBF文件我發現mysql&#xff0c;和Oracle都能直接對DBF文件進行導入。在導入過程中發現這些數據庫并不能識別這些文件。 通過百度找到了打開這種文件的軟件Visual FoxPro、Access&#xff0c;用它們打開后出…

Scrum 沖刺 第一日

Scrum 沖刺 第一日 站立式會議燃盡圖Alpha 階段認領任務明日任務安排項目預期任務量成員貢獻值計算規則今日貢獻量參考資料站立式會議 返回目錄 燃盡圖 返回目錄 Alpha 階段認領任務 學號組員分工用時20162309邢天岳補充說明書&部分測試18h20162311張之睿編寫代碼20h201623…

淺析 NodeJs 的幾種文件路徑

Node 中的文件路徑大概有 __dirname, __filename, process.cwd(), ./ 或者 ../&#xff0c;前三個都是絕對路徑&#xff0c;為了便于比較&#xff0c;./ 和 ../ 我們通過 path.resolve(./)來轉換為絕對路徑。 先看一個簡單的栗子&#xff1a; 假如我們有這樣的文件結構&#xf…

Vue項目代碼改進(二)—— element-UI的消息顯示時間修改

Message 消息提示 Options duration 顯示時間, 毫秒。設為 0 則不會自動關閉 — 默認值3000 全局重寫 element 的message 消息提示,修改時間&#xff0c;在main.js里 Vue.prototype.$message function (msg) {ElementUI.Message(msg) } Vue.prototype.$message.success func…

es6 --- 使用node的memoryUsage檢測WeakMap()

打開node命令行 $ node --expose-gc// --expose-gc:表示允許手動執行垃圾回收機制// 手動執行一次垃圾回收,保證獲取的內存使用狀態準確 > global.gc();// 查看內存占用的初始狀態, > process.memoryUsage();可以發現初始用了4.7MB左右 // 創建一個WeakMap()實例wm >…

遍歷字典

Python支持對字典的遍歷&#xff0c;有多種遍歷字典的方式&#xff1a;所有的鍵值對&#xff0c;鍵或者值。 遍歷所有的鍵值對&#xff1a; people {name:winter, age:25, sex:man, }for key,value in people.items():print("\nkey:"key)print("value…

Flexbox 布局

Flexbox 是 flexible box 的簡稱&#xff08;愚人碼頭注&#xff1a;意思是“靈活的盒子容器”&#xff09;&#xff0c;是 CSS3 引入的新的布局模式。它決定了元素如何在頁面上排列&#xff0c;使它們能在不同的屏幕尺寸和設備下可預測地展現出來。 它之所以被稱為 Flexbox &a…

利用jQuery和bootstrap更改radio樣式

<div class"container body-content"><div class"row"><div class"text-center col-xs-12"><h3>標題</h3><div class"well well-sm"><div class"btn-group" data-toggle"butto…

將markdown編譯為HTML和PDF

使用gulp搭建markdown編譯環境 1. 執行npm init 進行項目初始化得到package.json 2. 全局安裝gulp &#xff1a;npm install gulp --global; 3. 在項目中安裝gulp依賴&#xff1a;npm install gulp --save-dev; 4. 創建gulpfile.js文件設置任務&#xff1a; var gulp require…

捕獲異常的兩種方式

捕獲異常的兩種方式方法一 #codingutf-8 import systry:with open("ddd.txt", "r") as f:data f.read()print data except:err sys.exc_info()print errsys.exc_info()返回三元組&#xff0c;分別是&#xff0c;異常類型、異常值、異常追溯地址方法二 #c…

Vue項目代碼改進(三)—— Cookie、LocalStorage和SessionStorage的使用

存在問題&#xff1a; 如果在退出頁面時&#xff0c;沒有點擊“退出”按鈕&#xff0c;而是直接關閉頁面&#xff0c;token并沒有被清除&#xff0c;依然能通過訪問http://localhost:8080/#/ 直接進入主頁。 原因&#xff1a; 使用了localStorage而非sessionStorage或Cookie 一…

es6 --- Proxy實例的get方法

寫一個攔截函數,訪問目標對象不存在屬性時,會拋出不存在該屬性的錯誤 如果存在該屬性時,就返回其值. var person {name: "張三" };var proxy new Proxy(person, {get: function(target, property) {if (property in target) {return target[property];} else {thr…

webstorm前端常用快捷鍵

Ctrl / 行注釋/取消行注釋 Ctrl Shift / 塊注釋/取消塊注釋 Ctrl W 選擇代碼塊&#xff0c;一般是增量選擇 Ctrl Shift W 上個快捷鍵的回退&#xff0c;減量選擇代碼 Alt Q 上下文信息 A…

sql常識

1.UNION與UNION ALL的區別UNION去重且排序UNION ALL不去重不排序2.sql語句or與union all的執行效率比較:union all>union> in >or 用一張表更新另一張表&#xff1a; UPDATE ASET A1 B1, A2 B2, A3 B3FROM A LEFT JOIN B ON A.ID B.IDMS SQL SERVER的寫法&#xf…

優秀導航網站收集

一納米學習網站導航 泡面吧導航 納威安全導航 設計師導航網址 優設圖書導航 極客導航 大前端網址導航 前端導航 轉載于:https://www.cnblogs.com/fazero/p/7976684.html

Vue項目代碼改進(四)—— 在使用ElementUI時點擊同一個路由,頁面報錯

這個不可描述的問題是&#xff1a;在使用ElementUI時點擊同一個路由&#xff0c;頁面報錯。 錯誤代碼如下&#xff1a; element-ui.common.js?ccbf:3339 NavigationDuplicated {_ name: "NavigationDuplicated", name: "NavigationDuplicated", message…