成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

細說 Java 的深拷貝和淺拷貝

開發 開發工具
任何變成語言中,其實都有淺拷貝和深拷貝的概念,Java 中也不例外。在對一個現有的對象進行拷貝操作的時候,是有淺拷貝和深拷貝之分的,他們在實際使用中,區別很大,如果對其進行混淆,可能會引發一些難以排查的問題。

 [[200191]]

一、前言

任何變成語言中,其實都有淺拷貝和深拷貝的概念,Java 中也不例外。在對一個現有的對象進行拷貝操作的時候,是有淺拷貝和深拷貝之分的,他們在實際使用中,區別很大,如果對其進行混淆,可能會引發一些難以排查的問題。

本文就在 Java 中的深拷貝和淺拷貝做一個詳細的解說。

二、什么是淺拷貝和深拷貝

首先需要明白,淺拷貝和深拷貝都是針對一個已有對象的操作。那先來看看淺拷貝和深拷貝的概念。

在 Java 中,除了基本數據類型(元類型)之外,還存在 類的實例對象 這個引用數據類型。而一般使用 『 = 』號做賦值操作的時候。對于基本數據類型,實際上是拷貝的它的值,但是對于對象而言,其實賦值的只是這個對象的引用,將原對象的引用傳遞過去,他們實際上還是指向的同一個對象。

而淺拷貝和深拷貝就是在這個基礎之上做的區分,如果在拷貝這個對象的時候,只對基本數據類型進行了拷貝,而對引用數據類型只是進行了引用的傳遞,而沒有真實的創建一個新的對象,則認為是淺拷貝。反之,在對引用數據類型進行拷貝的時候,創建了一個新的對象,并且復制其內的成員變量,則認為是深拷貝。

所以到現在,就應該了解了,所謂的淺拷貝和深拷貝,只是在拷貝對象的時候,對 類的實例對象 這種引用數據類型的不同操作而已。

總結來說:

1、淺拷貝:對基本數據類型進行值傳遞,對引用數據類型進行引用傳遞般的拷貝,此為淺拷貝。

2、深拷貝:對基本數據類型進行值傳遞,對引用數據類型,創建一個新的對象,并復制其內容,此為深拷貝。

三、Java 中的 clone()

3.1 Object 上的 clone() 方法

在 Java 中,所有的 Class 都繼承自 Object ,而在 Object 上,存在一個 clone() 方法,它被聲明為了 protected ,所以我們可以在其子類中,使用它。

而無論是淺拷貝還是深拷貝,都需要實現 clone() 方法,來完成操作。

 

可以看到,它的實現非常的簡單,它限制所有調用 clone() 方法的對象,都必須實現 Cloneable 接口,否者將拋出 CloneNotSupportedException 這個異常。最終會調用 internalClone() 方法來完成具體的操作。而 internalClone() 方法,實則是一個native 的方法。對此我們就沒必要深究了,只需要知道它可以 clone() 一個對象得到一個新的對象實例即可。

而反觀 Cloneable 接口,可以看到它其實什么方法都不需要實現。對他可以簡單的理解只是一個標記,是開發者允許這個對象被拷貝。

3.2 淺拷貝

先來看看淺拷貝的例子。

首先創建一個 class 為 FatherClass ,對其實現 Cloneable 接口,并且重寫 clone()方法。

然后先正常 new 一個 FatherClass 對象,再使用 clone() 方法創建一個新的對象。

 

***看看輸出的 Log :

  1. I/cxmyDev: fatherA == fatherB : false  
  2. I/cxmyDev: fatherA hash : 560973324  
  3. I/cxmyDev: fatherB hash : 560938740  
  4. I/cxmyDev: fatherA name : 張三  
  5. I/cxmyDev: fatherB name : 張三 

可以看到,使用 clone() 方法,從 == 和 hashCode 的不同可以看出,clone() 方法實則是真的創建了一個新的對象。

但這只是一次淺拷貝的操作。

來驗證這一點,繼續看下去,在 FatherClass 中,還有一個 ChildClass 的對象 child ,clone() 方法是否也可以正常復制它呢?改寫一個上面的 Demo。

看到,這里將其內的 child 進行負責,用起來看看輸出的 Log 效果。

  1. I/cxmyDev: fatherA == fatherB : false 
  2. I/cxmyDev: fatherA hash : 560975188 
  3. I/cxmyDev: fatherB hash : 560872384 
  4. I/cxmyDev: fatherA name : 張三 
  5. I/cxmyDev: fatherB name : 張三 
  6. I/cxmyDev: ================== 
  7. I/cxmyDev: A.child == B.child : true 
  8. I/cxmyDev: fatherA.child hash : 560891436 
  9. I/cxmyDev: fatherB.child hash : 560891436 

從***對 child 的輸出可以看到,A 和 B 的 child 對象,實際上還是指向了同一個對象,只對對它的引用進行了傳遞。

3.3 深拷貝

既然已經了解了對 clone() 方法,只能對當前對象進行淺拷貝,引用類型依然是在傳遞引用。

那么,如何進行一個深拷貝呢?

比較常用的方案有兩種:

  1. 序列化(serialization)這個對象,再反序列化回來,就可以得到這個新的對象,無非就是序列化的規則需要我們自己來寫。
  2. 繼續利用 clone() 方法,既然 clone() 方法,是我們來重寫的,實際上我們可以對其內的引用類型的變量,再進行一次 clone()。

繼續改寫上面的 Demo ,讓 ChildClass 也實現 Cloneable 接口。

最重要的代碼就在 FatherClass.clone() 中,它對其內的 child ,再進行了一次 clone() 操作。

再來看看輸出的 Log。

  1. I/cxmyDev: fatherA == fatherB : false 
  2. I/cxmyDev: fatherA hash : 561056732 
  3. I/cxmyDev: fatherB hash : 561057344 
  4. I/cxmyDev: fatherA name : 張三 
  5. I/cxmyDev: fatherB name : 張三 
  6. I/cxmyDev: ================== 
  7. I/cxmyDev: A.child == B.child : false 
  8. I/cxmyDev: fatherA.child hash : 561057304 
  9. I/cxmyDev: fatherB.child hash : 561057360 

可以看到,對 child 也進行了一次拷貝,這實則是對 ChildClass 進行的淺拷貝,但是對于 FatherClass 而言,則是一次深拷貝。

其實深拷貝的思路都差不多,序列化也好,使用 clone() 也好,實際上都是需要我們自己來編寫拷貝的規則,最終實現深拷貝的目的。

如果想要實現深拷貝,推薦使用 clone() 方法,這樣只需要每個類自己維護自己即可,而無需關心內部其他的對象中,其他的參數是否也需要 clone() 。

四、總結

到現在基本上就已經梳理清楚,Java 中淺拷貝和深拷貝的概念了。

實則淺拷貝和深拷貝只是相對的,如果一個對象內部只有基本數據類型,那用 clone() 方法獲取到的就是這個對象的深拷貝,而如果其內部還有引用數據類型,那用 clone() 方法就是一次淺拷貝的操作。

【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2021-07-16 12:33:24

Javascript深拷貝淺拷貝

2009-05-19 17:28:44

深拷貝淺拷貝clone()

2021-09-27 11:07:11

深拷貝淺拷貝內存

2022-07-26 08:07:03

Python淺拷貝深拷貝

2018-09-26 14:37:17

JavaScript前端編程語言

2024-03-15 15:03:23

2020-08-03 08:24:26

原型模式拷貝

2021-01-08 06:15:09

深拷貝淺拷貝寫時拷貝

2020-10-12 08:35:22

JavaScript

2023-05-17 08:42:46

深拷貝Golang

2024-02-05 22:56:16

C++拷貝開發

2018-05-10 14:20:18

前端JavaScript深拷貝

2022-09-30 15:03:09

C語言深拷貝淺拷貝

2022-11-07 11:37:27

深拷貝淺拷貝底層

2024-04-17 09:01:08

Python深拷貝淺拷貝

2023-05-17 07:36:00

淺拷貝深拷貝對象

2020-06-23 08:41:47

JavaScript開發技術

2023-09-22 12:21:33

Python深拷貝淺拷貝

2021-10-18 09:01:01

前端賦值淺拷貝

2019-02-25 08:58:16

Python深拷貝淺拷貝
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩福利一区 | 亚洲免费在线 | 密桃av| 青青草原综合久久大伊人精品 | 欧美无乱码久久久免费午夜一区 | 欧美中文在线 | 欧美一级片在线看 | 久久国产日本 | 国产成人福利在线 | 中文字幕一区二区三区日韩精品 | 免费观看a级毛片在线播放 黄网站免费入口 | 久久久蜜臀国产一区二区 | 免费日韩av网站 | 成人国产综合 | 青青激情网 | 青青草在线视频免费观看 | 国产精品久久久久国产a级 欧美日韩国产免费 | 国内成人免费视频 | 91精品国产91久久久久久最新 | 中文字幕在线一区二区三区 | 午夜影视| www.午夜| 欧美视频一区二区三区 | av毛片在线免费观看 | 黄色一级大片在线免费看产 | 日韩高清三区 | 久久香焦 | 99re在线 | 久久国产一区二区 | 欧美精品一区二区在线观看 | 99精品久久久久久中文字幕 | 欧美久久一区二区 | 在线免费观看毛片 | 午夜伊人 | 祝你幸福电影在线观看 | 日本一本视频 | 亚洲国产日韩欧美 | 日韩美av | 在线国产欧美 | 综合一区二区三区 | 91亚洲免费 |