日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java数组的clone方法_深入浅出,如何更彻底地理解Java数组的clone方法

發(fā)布時(shí)間:2025/4/5 java 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java数组的clone方法_深入浅出,如何更彻底地理解Java数组的clone方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說在前面

在進(jìn)入理解clone前,我們需要對“基本數(shù)據(jù)類型”和“引用數(shù)據(jù)類型”的存儲(chǔ)模式有一個(gè)清晰的認(rèn)識(shí)。

基本數(shù)據(jù)類型,變量的內(nèi)容保存的是實(shí)際的值;引用數(shù)據(jù)類型,變量的內(nèi)容保存的是一個(gè)地址,該地址的指向才是實(shí)際的值。

int baseData = 5; // 基本數(shù)據(jù)類型,baseData對應(yīng)的內(nèi)存保存的是具體的值:5

System.out.println(baseData); // 直接打印,返回:5

HandClass handData = new HandClass(); //引用數(shù)據(jù)類型,handData對應(yīng)的內(nèi)存保存的是一個(gè)16進(jìn)制的內(nèi)存地址,該地址才是保存值的地方

System.out.println(handData); //直接打印,返回內(nèi)存地址:HandClass@3c6f579

需要注意的是,不管是基本數(shù)據(jù)類型,還是引用數(shù)據(jù)類型,賦值(=)操作都是將變量自身內(nèi)容賦值給另一個(gè)變量。唯一不同的是,我們常用操作中,基本數(shù)據(jù)類型是針對自身內(nèi)容(值)進(jìn)行的;而引用數(shù)據(jù)類型則是針對自身內(nèi)容(地址)的指向進(jìn)行的。

int data1 = 1;

int data2 = data1; // 將data1的內(nèi)容(1)賦值給data2

System.out.println(data1); // 返回:1

System.out.println(data2); // 返回:1

data1 = 2; // 即使修改data1的內(nèi)容,data2不受影響

System.out.println(data1); // 返回:2

System.out.println(data2); // 返回:1

System.out.println("--------------------");

HandClass handData1 = new HandClass();

handData1.ele = 1;

HandClass handData2 = handData1; // 將handData1的內(nèi)容(實(shí)際內(nèi)存地址)賦值給handData2

System.out.println(handData1.ele); // 返回:1

System.out.println(handData2.ele); // 返回:1

// 直接將handData1和handData2打印出來,返回相同的內(nèi)容(地址)

System.out.println(handData1); // 返回:HandClass@66edc3a2

System.out.println(handData2); // 返回:HandClass@66edc3a2

handData1.ele = 2; // 修改handData1.ele的內(nèi)容,handData2受影響,因?yàn)樗麄兊膬?nèi)容相同(指向了同一個(gè)內(nèi)存)

System.out.println(handData1.ele); // 返回:2

System.out.println(handData2.ele); // 返回:2

handData1 = new HandClass(); // 為handData1開辟一個(gè)新的內(nèi)地址,并將該地址賦值給handData1的內(nèi)容

// 直接將handData1和handData2打印出來,返回不相同的內(nèi)容(地址):handData1的內(nèi)容

System.out.println(handData1); // 返回:HandClass@3ced0338

System.out.println(handData2); // 返回:HandClass@66edc3a2

handData1.ele = 3; // 此時(shí)再次修改handData1.ele的內(nèi)容,handData2不受影響,因?yàn)樗麄兊膬?nèi)容已經(jīng)不相同(指向了不同的內(nèi)存)

System.out.println(handData1.ele); // 返回:3

System.out.println(handData2.ele); // 返回:2

總結(jié):無論是基本數(shù)據(jù)類型,還是引用數(shù)據(jù)類型,賦值操作的實(shí)質(zhì)都是內(nèi)容賦值。

進(jìn)入正題

先拋出結(jié)論:數(shù)組的clone方法,本質(zhì)是“降維賦值”。即將數(shù)組進(jìn)行降低維度后,開辟一個(gè)與之一摸一樣的內(nèi)存空間,然后進(jìn)行遍歷賦值。

(此文不討論數(shù)組的存儲(chǔ)模式,對數(shù)組存儲(chǔ)模式比較薄弱的朋友,請先自行了解)

一維數(shù)組:

一維數(shù)組降維后是一組變量。

int intArrayA[] = new int[]{1,2,3};

int intArrayB[] = intArrayA.clone(); // 將intArrayA的克隆賦值給intArrayB

/**

* 先對intArrayA進(jìn)行降維

* 降維后,變成一組變量:intArrayA[0]、intArrayA[1]、intArrayA[2]

* 在內(nèi)存中申請一組與intArrayA類型、長度相同數(shù)組: int tmp[] = new int[2];

* 將變量進(jìn)行遍歷賦值:tmp[0]=intArrayA[0]、tmp[1]=intArrayA[1]、tmp[2]=intArrayA[2]

* 將數(shù)組tmp的內(nèi)容(地址)返回(注:tmp是一個(gè)數(shù)組,即屬于引用類型)

* */

System.out.println(intArrayA[1]); // 返回:2

System.out.println(intArrayB[1]); // 返回:2

intArrayA[1] = 100;

System.out.println(intArrayA[1]); // 返回:100

System.out.println(intArrayB[1]); // 返回:2

/**

* 上述結(jié)論:"無論是基本數(shù)據(jù)類型,還是引用數(shù)據(jù)類型,賦值操作的實(shí)質(zhì)都是內(nèi)容賦值。"

* intArrayA降維后,intArrayA[0]~intArrayA[2]是一組基本數(shù)據(jù)類型的變量

* 賦值的時(shí)候,將intArrayA[0]~intArrayA[2]的內(nèi)容(實(shí)際的值)賦值給tmp[0]~tmp[2]

* 而后tmp[0]~tmp[2]組成的tmp的內(nèi)容(一個(gè)地址)又返回給intArrayB

* 因此,intArrayB[1]和intArrayA[1]的內(nèi)容是一致的,他們的內(nèi)容均是"2"

* 當(dāng)我們通過intArrayA[1]進(jìn)行操作時(shí),僅僅是修改自身的內(nèi)容,intArrayB[1]不會(huì)受到影響

* */

System.out.println("--------------------");

HandClass handArrayA[] = new HandClass[]{new HandClass(),new HandClass(),new HandClass()};

HandClass handArrayB[] = handArrayA.clone();

/**

* 先對handArrayA進(jìn)行降維

* 降維后,編程一組變量:handArrayA[0]、handArrayA[1]、handArrayA[2]

* 在內(nèi)存中申請一組與handArrayA類型長度、相同數(shù)組: HandClass tmp[] = new HandClass[2];

* 將變量進(jìn)行遍歷賦值:tmp[0]=handArrayA[0]、tmp[1]=handArrayA[1]、tmp[2]=handArrayA[2]

* 將數(shù)組tmp的內(nèi)容(地址)返回(注:tmp是一個(gè)數(shù)組,即屬于引用類型)

* */

System.out.println(handArrayA[1].ele); // 返回:0 注:此處的0,是實(shí)例化時(shí),系統(tǒng)賦與的默認(rèn)初始值

System.out.println(handArrayB[1].ele); // 返回:0

handArrayA[1].ele = 100;

System.out.println(handArrayA[1]); // 返回:HandClass@7b1ddcde

System.out.println(handArrayB[1]); // 返回:HandClass@7b1ddcde

System.out.println(handArrayA[1].ele); // 返回:100

System.out.println(handArrayB[1].ele); // 返回:100

/**

* 上述結(jié)論:"無論是基本數(shù)據(jù)類型,還是引用數(shù)據(jù)類型,賦值操作的實(shí)質(zhì)都是內(nèi)容賦值。"

* handArrayA降維后,handArrayA[0]~handArrayA[2]是一組引用類型的變量

* 賦值的時(shí)候,將handArrayA[0]~handArrayA[2]的內(nèi)容(一個(gè)地址)賦值給tmp[0]~tmp[2]

* 而后tmp[0]~tmp[2]組成的tmp的內(nèi)容(一個(gè)地址)又返回給handArrayB

* 因此,handArrayB[1]和handArrayA[1]的內(nèi)容是一致的,他們均指向了同一個(gè)內(nèi)存

* 當(dāng)我們通過handArrayA[1]進(jìn)行操作時(shí)(實(shí)際是修改其內(nèi)容對應(yīng)的實(shí)際對象的內(nèi)容),handArrayB[1](內(nèi)容所指向的實(shí)際對象)也會(huì)受到影響

* */

二維及多維數(shù)組:

二維數(shù)組降維后是一組數(shù)組,數(shù)組本身就是引用類型。因此二維及多維的數(shù)組的克隆中的賦值,均屬于引用類型賦值。

int multIntArrayA[][] = new int[][]{{11,12,13},{21,22,23}};

int multIntArrayB[][] = multIntArrayA.clone();

/**

* 先對multIntArrayA進(jìn)行降維

* 降維后,變成一組一維數(shù)組:multIntArrayA[0]、multIntArrayA[1]

* 在內(nèi)存中申請一組與multIntArray類型、長度相同數(shù)組: int tmp[][] = new int[2][3];

* 將數(shù)組進(jìn)行遍歷賦值:tmp[0]=multIntArray[0]、tmp[1]=multIntArray[1],

* 特別著重說明的事,這里是數(shù)組(引用類型)的賦值,而并非數(shù)組元素(int類型)的賦值

* 將數(shù)組tmp的內(nèi)容(地址)返回(注:tmp是一個(gè)數(shù)組,即屬于引用類型)

* */

System.out.println(multIntArrayA[0][1]); // 返回:12

System.out.println(multIntArrayB[0][1]); // 返回:12

multIntArrayA[0][1] = 66;

System.out.println(multIntArrayA[0][1]); // 返回:66

System.out.println(multIntArrayB[0][1]); // 返回:66

/**

* 我們注意到,multIntArrayB已經(jīng)受到了multIntArrayA的影響

* 因?yàn)閏lone只會(huì)降低一個(gè)維度后進(jìn)行遍歷賦值,即:將multIntArrayA[0]的內(nèi)容(一個(gè)地址)賦值給multIntArrayB[0]

* 當(dāng)我們操作multIntArrayA[0][1]時(shí),實(shí)際是操作了multIntArrayA[0]的內(nèi)容所指向的實(shí)際的數(shù)組第一個(gè)元素的值

* multIntArrayB[0]保存的內(nèi)容與multIntArrayA[0]一致,同樣指向的是同一個(gè)數(shù)組

* 因此multIntArrayB[0][1]全等于multIntArrayA[0][1](變量自身一模一樣)

* 再次也可以明確,clone的降維,只會(huì)降低一個(gè)維度

* 若要數(shù)組元素也克隆,則需要再次clone,以將維度降低至數(shù)組元素

* */

multIntArrayB[0] = multIntArrayA[0].clone();

multIntArrayA[0][1] = 77;

System.out.println(multIntArrayA[0][1]); // 返回:77

System.out.println(multIntArrayB[0][1]); // 返回:66

/**

* 可以看出,當(dāng)我們對multIntArrayA[0]進(jìn)行克隆

* multIntArrayA[0]降維后,就是一組基本數(shù)據(jù)類型的變量(int)

* 因此multIntArrayB[0]中的各個(gè)元素(基本數(shù)據(jù)類型)全等于multIntArrayA[0]中的元素,而是一個(gè)"克隆品"

* 當(dāng)我們修改multIntArrayA[0][1]后,multIntArrayB[0][1]并不會(huì)隨之變化

* 為了加強(qiáng)驗(yàn)證這一現(xiàn)象,我們將"基本數(shù)據(jù)類型"改為"引用數(shù)據(jù)類型"

* 如果我們的猜想沒錯(cuò),進(jìn)行上述操作后,最后輸出的應(yīng)該也一樣是"77",而不是"66"

* */

System.out.println("--------------------");

HandClass multHandArrayA[][] = new HandClass[][]{{new HandClass(),new HandClass(),new HandClass()},{new HandClass(),new HandClass(),new HandClass()}};

HandClass multHandArrayB[][] = multHandArrayA.clone();

System.out.println(multHandArrayA[0][1]); // 返回:HandClass@7b1ddcde

System.out.println(multHandArrayB[0][1]); // 返回:HandClass@7b1ddcde

multHandArrayA[0][1].ele = 66;

System.out.println(multHandArrayA[0][1].ele); // 返回:66

System.out.println(multHandArrayB[0][1].ele); // 返回:66

multHandArrayB[0] = multHandArrayA[0].clone();

multHandArrayA[0][1].ele = 77;

System.out.println(multHandArrayA[0][1].ele); // 返回:77

System.out.println(multHandArrayB[0][1].ele); // 返回:77

/**

* 如果只是進(jìn)行multHandArrayA的clone,那么"基本數(shù)據(jù)類型"和"引用數(shù)據(jù)類型"是一樣的

* 但是,當(dāng)我們再次對multHandArrayA[0]進(jìn)行克隆后,效果就不一樣了

* 由于multHandArrayA[0]降維后,是一組引用數(shù)據(jù)類型的數(shù)組

* 因此multHandArrayB[0]中的各個(gè)元素(引用數(shù)據(jù)類型)的內(nèi)容與multIntArrayA[0]中對應(yīng)的元素一致,即指向同一個(gè)地址

* 當(dāng)我們修改multHandArrayA[0][1]的值(實(shí)際修改的是它內(nèi)容指向的地址對應(yīng)的實(shí)際對象),multHandArrayB[0][1]也會(huì)隨之變化

* */

總結(jié):Java中,數(shù)組的克隆(clone)只會(huì)降一次維,而后開辟一塊新的空間,遍歷所有元素進(jìn)行賦值操作。

值得一提

一維數(shù)組,由于降維后就是數(shù)組的基本元素,因此看起來就像是進(jìn)行了“深拷貝”,實(shí)際是錯(cuò)誤的。只有基本數(shù)據(jù)類型的一維數(shù)組的clone才是“深拷貝”的效果;引用數(shù)據(jù)類型的一維數(shù)組clone,還需要額外進(jìn)行“對象拷貝”;

二維或者多維數(shù)組可以通過遞歸方式,進(jìn)行更低維度(直至降低至一維)的clone,從而達(dá)到“深拷貝”的目的。

總結(jié)

以上是生活随笔為你收集整理的java数组的clone方法_深入浅出,如何更彻底地理解Java数组的clone方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亚洲在线视频网站 | 黑人操亚洲女人 | 成人高清免费 | 91福利区| 午夜福利视频合集1000 | 亚洲无av在线中文字幕 | 欧美在线激情视频 | 精品国产一区二区三区日日嗨 | 成人一级免费视频 | 亚洲a∨无码无在线观看 | 黄网在线看 | 91国语对白 | 少妇人妻偷人精品视频蜜桃 | 国产亚洲欧美在线 | 91精品又粗又猛又爽 | 久草福利资源在线观看 | 国产一级性生活 | 久久久久久久蜜桃 | 国产精品毛片一区二区在线看舒淇 | 精品久久久蜜桃 | 亚洲人视频在线观看 | av官网| 免费黄色网址在线观看 | 一区二区三区高清不卡 | 亚洲 欧美 另类 综合 偷拍 | 一区一区三区产品乱码 | 呦呦视频在线观看 | 黄色工厂这里只有精品 | 一区不卡av | 激情黄色小说视频 | 天天操操操 | 国产一区二区三区四区五区美女 | 日产精品久久久久久久 | 国产69久久精品成人看 | 无码精品一区二区三区在线 | 99精品视频一区二区 | 亚洲精品在线不卡 | 在线观看中文字幕一区 | 91国内 | 国产白丝一区二区三区 | 色婷婷综合成人av | jizz国产在线| 91资源站 | 射影院| 日本熟妇色xxxxx日本免费看 | 日本一区二区三区欧美 | 青青草在线免费视频 | 日日爱影视 | 色亭亭| 日韩欧美猛交xxxxx无码 | 午夜免费大片 | 成人综合在线观看 | 麻豆视频在线 | 一本大道久久a久久综合婷婷 | av午夜天堂| 国精产品一区一区三区在线 | 日本猛少妇色xxxxx猛叫 | 一区二区三区在线观看av | 毛片视频网站在线观看 | www.99re7.com | 精品无码久久久久成人漫画 | 国产精品xx| 精品国产一区二区三区久久狼黑人 | 国产日产欧美一区二区三区 | 国产一区福利 | 日中文字幕| 三级大片在线观看 | 日日爽日日操 | 最新毛片网站 | 五月天亚洲色图 | 欧美精品一区二区三区在线播放 | a视频在线观看免费 | 亚洲AV成人午夜无码精品久久 | 亚洲成人中文 | 天天射网| 色综合久久久久综合体桃花网 | 日韩不卡高清 | 亚洲人在线观看视频 | 偷拍亚洲欧美 | 欧美日韩成人 | 在线视频 亚洲 | 成人欧美一区二区三区黑人动态图 | 影音先锋在线看 | japan高清日本乱xxxxx | 黄色av导航 | 日本寂寞少妇 | 亚洲成人第一页 | 国产伦精品一区二区三区高清版 | 国产高清黄色 | 中文字幕日韩久久 | 亚洲成人免费视频 | 一级大黄色片 | 黄色在线观看国产 | 日本不卡高字幕在线2019 | 成人香蕉视频在线观看 | 免费a级 | 亚洲精品久久久久久无码色欲四季 | 午夜性影院 | 999热精品 |