1. 程式人生 > >Java的深拷貝最新版欣欣十三水棋牌_房卡十三水全套棋牌原始碼下載和淺拷貝

Java的深拷貝最新版欣欣十三水棋牌_房卡十三水全套棋牌原始碼下載和淺拷貝

 關於Java的深拷貝最新版欣欣十三水棋牌_房卡十三水全套棋牌原始碼下載 super-mans.com Q.3393756657和淺拷貝,簡單來說就是建立一個和已知物件一模一樣的物件。可能日常編碼過程中用的不多,但是這是一個面試經常會問的問題,而且瞭解深拷貝和淺拷貝的原理,對於Java中的所謂值傳遞或者引用傳遞將會有更深的理解。

回到頂部

1、建立物件的5種方式

  ①、通過 new 關鍵字

  這是最常用的一種方式,通過 new 關鍵字呼叫類的有參或無參構造方法來建立物件。比如 Object obj = new Object();

  ②、通過 Class 類的 newInstance() 方法

  這種預設是呼叫類的無參構造方法建立物件。比如 Person p2 = (Person) Class.forName("com.ys.test.Person").newInstance();

  ③、通過 Constructor 類的 newInstance 方法

  這和第二種方法類時,都是通過反射來實現。通過 java.lang.relect.Constructor 類的 newInstance() 方法指定某個構造器來建立物件。

  Person p3 = (Person) Person.class.getConstructors()[0].newInstance();

  實際上第二種方法利用 Class 的 newInstance() 方法建立物件,其內部呼叫還是 Constructor 的 newInstance() 方法。

  ④、利用 Clone 方法

  Clone 是 Object 類中的一個方法,通過 物件A.clone() 方法會建立一個內容和物件 A 一模一樣的物件 B,clone 克隆,顧名思義就是建立一個一模一樣的物件出來。

  Person p4 = (Person) p3.clone();

  ⑤、反序列化

  序列化是把堆記憶體中的 Java 物件資料,通過某種方式把物件儲存到磁碟檔案中或者傳遞給其他網路節點(在網路上傳輸)。而反序列化則是把磁碟檔案中的物件資料或者把網路節點上的物件資料,恢復成Java物件模型的過程。

  具體如何實現可以參考我 這篇博文

回到頂部

3、Clone 方法

  本篇部落格我們講解的是 Java 的深拷貝和淺拷貝,其實現方式正是通過呼叫 Object 類的 clone() 方法來完成。在 Object.class 類中,原始碼為:

protected native Object clone() throws
CloneNotSupportedException;

  這是一個用 native 關鍵字修飾的方法,關於native關鍵字有一篇部落格專門有介紹,不理解也沒關係,只需要知道用 native 修飾的方法就是告訴作業系統,這個方法我不實現了,讓作業系統去實現。具體怎麼實現我們不需要了解,只需要知道 clone方法的作用就是複製物件,產生一個新的物件。那麼這個新的物件和原物件是什麼關係呢?

回到頂部

4、基本型別和引用型別

  這裡再給大家普及一個概念,在 Java 中基本型別和引用型別的區別。

  在 Java 中資料型別可以分為兩大類:基本型別和引用型別。

  基本型別也稱為值型別,分別是字元型別 char,布林型別 boolean以及數值型別 byte、short、int、long、float、double。

  引用型別則包括類、介面、陣列、列舉等。

  Java 將記憶體空間分為堆和棧。基本型別直接在棧中儲存數值,而引用型別是將引用放在棧中,實際儲存的值是放在堆中,通過棧中的引用指向堆中存放的資料。

  

  上圖定義的 a 和 b 都是基本型別,其值是直接存放在棧中的;而 c 和 d 是 String 宣告的,這是一個引用型別,引用地址是存放在 棧中,然後指向堆的記憶體空間。

  下面 d = c;這條語句表示將 c 的引用賦值給 d,那麼 c 和 d 將指向同一塊堆記憶體空間。

回到頂部

5、淺拷貝

  我們看如下這段程式碼:

 View Code View Code

  這是一個我們要進行賦值的原始類 Person。下面我們產生一個 Person 物件,並呼叫其 clone 方法複製一個新的物件。

  注意:呼叫物件的 clone 方法,必須要讓類實現 Cloneable 介面,並且覆寫 clone 方法。

測試:

 View Code

  列印結果為:

  

  首先看原始類 Person 實現 Cloneable 介面,並且覆寫 clone 方法,它還有三個屬性,一個引用型別 String定義的 pname,一個基本型別 int定義的 page,還有一個引用型別 Address ,這是一個自定義類,這個類也包含兩個屬性 pprovices 和 city 。

  接著看測試內容,首先我們建立一個Person 類的物件 p1,其pname 為zhangsan,page為21,地址類 Address 兩個屬性為 湖北省和武漢市。接著我們呼叫 clone() 方法複製另一個物件 p2,接著列印這兩個物件的內容。

  從第 1 行和第 3 行列印結果:

  p1:[email protected]

  p2:[email protected]

  可以看出這是兩個不同的物件。

  從第 5 行和第 6 行列印的物件內容看,原物件 p1 和克隆出來的物件 p2 內容完全相同。

  程式碼中我們只是更改了克隆物件 p2 的屬性 Address 為湖北省荊州市(原物件 p1 是湖北省武漢市) ,但是從第 7 行和第 8 行列印結果來看,原物件 p1 和克隆物件 p2 的 Address 屬性都被修改了。

  也就是說物件 Person 的屬性 Address,經過 clone 之後,其實只是複製了其引用,他們指向的還是同一塊堆記憶體空間,當修改其中一個物件的屬性 Address,另一個也會跟著變化。

  

  淺拷貝:建立一個新物件,然後將當前物件的非靜態欄位複製到該新物件,如果欄位是值型別的,那麼對該欄位執行復制;如果該欄位是引用型別的話,則複製引用但不復制引用的物件。因此,原始物件及其副本引用同一個物件。

回到頂部

6、深拷貝

  弄清楚了淺拷貝,那麼深拷貝就很容易理解了。

  深拷貝:建立一個新物件,然後將當前物件的非靜態欄位複製到該新物件,無論該欄位是值型別的還是引用型別,都複製獨立的一份。當你修改其中一個物件的任何內容時,都不會影響另一個物件的內容。

  

  那麼該如何實現深拷貝呢?Object 類提供的 clone 是隻能實現 淺拷貝的。

回到頂部

7、如何實現深拷貝?

  深拷貝的原理我們知道了,就是要讓原始物件和克隆之後的物件所具有的引用型別屬性不是指向同一塊堆記憶體,這裡有三種實現思路。

  ①、讓每個引用型別屬性內部都重寫clone() 方法

既然引用型別不能實現深拷貝,那麼我們將每個引用型別都拆分為基本型別,分別進行淺拷貝。比如上面的例子,Person 類有一個引用型別 Address(其實String 也是引用型別,但是String型別有點特殊,後面會詳細講解),我們在 Address 類內部也重寫 clone 方法。如下:

  Address.class:

 View Code

  Person.class 的 clone() 方法:

 View Code

  測試還是和上面一樣,我們會發現更改了p2物件的Address屬性,p1 物件的 Address 屬性並沒有變化。

  但是這種做法有個弊端,這裡我們Person 類只有一個 Address 引用型別,而 Address 類沒有,所以我們只用重寫 Address 類的clone 方法,但是如果 Address 類也存在一個引用型別,那麼我們也要重寫其clone 方法,這樣下去,有多少個引用型別,我們就要重寫多少次,如果存在很多引用型別,那麼程式碼量顯然會很大,所以這種方法不太合適。

  ②、利用序列化

序列化是將物件寫到流中便於傳輸,而反序列化則是把物件從流中讀取出來。這裡寫到流中的物件則是原始物件的一個拷貝,因為原始物件還存在 JVM 中,所以我們可以利用物件的序列化產生克隆物件,然後通過反序列化獲取這個物件。

  注意每個需要序列化的類都要實現 Serializable 介面,如果有某個屬性不需要序列化,可以將其宣告為 transient,即將其排除在克隆屬性之外。

 View Code

   因為序列化產生的是兩個完全獨立的物件,所有無論巢狀多少個引用型別,序列化都是能實現深拷貝的。

相關推薦

Java拷貝新版十三棋牌_十三全套棋牌原始碼下載拷貝

 關於Java的深拷貝最新版欣欣十三水棋牌_房卡十三水全套棋牌原始碼下載 super-mans.com Q.3393756657和淺拷貝,簡單來說就是建立一個和已知物件一模一樣的物件。可能日常編碼過程中用的不多,但是這是一個面試經常會問的問題,而且瞭解深拷貝和淺拷貝的原理,對

Java中的拷貝(復制)拷貝(復制)

alt public min import containe long serializa port nbsp 深拷貝(深復制)和淺拷貝(淺復制)是兩個比較通用的概念,尤其在C++語言中,若不弄懂,則會在delete的時候出問題,但是我們在這幸好用的是Java。雖然java

Java中的拷貝拷貝

detail tle pac err @override 復制對象 deep har 間接   淺談Java中的深拷貝和淺拷貝(轉載) 原文鏈接: http://blog.csdn.net/tounaobun/article/details/8491392 假如說你想復制一

macOs升級到10.13.1Beta || JAVA升級到新版之後PhpStorm菜單欄問題

cos cli 窗口 -m ora comm 出現 php tel macOs升級到10.13.1Beta || JAVA升級到最新版之後PhpStorm菜單欄會消失,估計不止出現在PhpStorm,一系列jetbrains的產品可能都會有這個問題,包括eclipise。

Java拷貝拷貝克隆克隆)

Java中建立物件有兩種方式: 通過new操作符建立一個物件 通過clone方法來複制一個物件 使用反序列化來建立一個物件 通過使用Class類的newInstance方法來建立一個物件 使用Constructor類的newInstance方法來建立一個物件 第一種方法,通過ne

碼出高效,碼出質量:雲棲大會的阿里Java開發手冊新版正式釋出!

"這是凝聚了阿里眾多Java開發人員多年經驗的Java開發手冊,強烈推薦Java程式設計師們看看,裡面的很多規則甚至是多次慘痛的故障經驗才形成的,另外在規則上諸如空格,命名等規範,很容易形成爭論,但對於一家公司而言,最重要的是要有統一規範(所以有些時候沒必要太糾結),對於程

java拷貝拷貝

淺拷貝: public class PrototypeClass implements Cloneable { private List<String> params = new ArrayList<String>(); @Over

java初學者基礎知識積累---(1)拷貝拷貝

本人是新手,為了以後的厚積薄發,也為了把自己的一些學習經驗寫下來與需要的朋友們分享,今兒特地早起理理!   定義:     淺拷貝:只複製一個物件,物件內部存在的、指向其他物件的陣列或者引用則不復制。     深拷貝:物件、物件內部的引用都複製。     為了更好的理解它們

Java拷貝拷貝

指向 supported not set null 元素 string new main 淺拷貝和深拷貝 在具體解釋Java深拷貝和淺拷貝之前,我們先看個例子,代碼如下: public class Thing implements Cloneable { // 定

Java拷貝拷貝(deepcopyshallowcopy)

原型模式要求用深拷貝(複製/克隆)的方式實現,對這個概念很模糊。在自己查了相關資料後,我將從三個方面講述深淺拷貝: 圖形表述深淺拷貝區別及特點 Object類中的clone()方法實現深淺拷貝 實際應用中深淺拷貝區別 一 圖形表述深淺拷貝區別及特點 前提:深淺拷貝基本

JAVA中對象的克隆及拷貝拷貝

output err 解釋 深拷貝和淺拷貝 color 賦值語句 的區別 num article 使用場景: 在日常的編程過程 中,經常會遇到,有一個對象OA,在某一時間點OA中已經包含了一些有效值 ,此時可能會需一個和OA完全相對的新對象OB,並且要在後面的操作中對OB

java中的拷貝拷貝

做專案時,可能會碰到這樣的一個問題,就是需要把一個物件的屬性完全拷貝到另一個物件上.當這個物件是個簡單物件(即屬性不包括對其他物件的引用)時用淺拷貝來完成物件的拷貝.即在實體類中實現Clonable介面,實現 public Object Clone()方法.通過呼叫父類的su

JAVA 物件的clone() 以及拷貝拷貝

java賦值是複製物件引用,如果我們想要得到一個物件的副本,使用賦 值操作是無法達到目的的: @Test public void testassign(){ Person p1=new Person(); p1.setAge(31); p1.setName

Java 中的拷貝拷貝

淺拷貝:對基本資料型別進行值傳遞,對引用資料型別進行引用傳遞般的拷貝,此為淺拷貝

js中的拷貝拷貝

所有 object 簡單的 col images new color 其他 java 深復制和淺復制只針對像 Object, Array 這樣的復雜對象的。簡單來說,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。 深淺拷貝 的主要區別就是:復制的是引用(地址)還

python學習系列--拷貝拷貝

深拷貝 淺拷貝 copy deepcopy概念普通情下,復制一個對象是不會新開辟內存空間的,只是把新的對象名稱指向原有的內存地址,這種操作其實不是算是拷貝,只是新的引用。把新的對象置於新的內存空間中,才是拷貝。在python中,深淺拷貝的區別實際上是拷貝的深度不同。操作常見的‘=’號就是一種拷貝方式。pyth

js 中引用類型 的拷貝 拷貝的區別

而是 query reac cat 避免 string val this 臨時 一、曾經在讀JQ源碼的時候,對深拷貝算是有了一點的理解。我們在項目中是不是經常會遇到這樣的問題呢? 後臺返回一個數組對象(引用類型).次數在頁面渲染中需要對部分數據進行處理 比如:銀行卡6234

js的命名空間 && 單體模式 && 變量拷貝拷貝 && 頁面彈窗設計

但是 界面 ket 模式 utf 針對 col con prop 說在前面:這是我近期開發或者看書遇到的一些點,覺得還是蠻重要的。 一、為你的 JavaScript 對象提供命名空間 <!DOCTYPE html> <html> <head&

拷貝拷貝

深拷貝 淺拷貝 #include <stdio.h> int main(int argc, char *argv[]) { char *p1="123"; char *p2="123"; char *p3="456"; const char *p4="ab

python的復制,拷貝拷貝的區別(轉)

pla bsp space 數據 深拷貝 淺拷貝 deepcopy 拷貝 tro 在python中,對象賦值實際上是對象的引用。當創建一個對象,然後把它賦給另一個變量的時候,python並沒有拷貝這個對象,而只是拷貝了這個對象的引用 一般有三種方法, alist=[1,2,