Java中的clone方法有什么作用
在C/C++語(yǔ)言中,常用到指針,指針不僅會(huì)給開發(fā)人員帶來(lái)使用上的不便,而且也是造成程序不穩(wěn)定的根源。
Java語(yǔ)言取消了指針的概念,但這只是在Java語(yǔ)言中沒(méi)有明確提供指針的概念與用法,而實(shí)質(zhì)上每個(gè)new語(yǔ)句返回的都是一個(gè)指針的引用,只不過(guò)在大部分情況下開發(fā)人員不需要關(guān)心如何去操作這個(gè)指針而已。
由于Java取消了指針的概念,因此開發(fā)人員在編程中往往忽略了對(duì)象和引用的區(qū)別。
測(cè)試:
輸出結(jié)果:

TestRef 中的 userBean 中的userName值改變了而 userAge的值未改變,原因是Java在處理基本數(shù)據(jù)類型(例如int、char、double等)時(shí),都是采用按值傳遞(傳遞的是輸入?yún)?shù)的復(fù)制)的方式執(zhí)行,除此之外的其他類型都是按引用傳遞(傳遞的是對(duì)象的一個(gè)引用)的方式執(zhí)行。對(duì)象除了在函數(shù)調(diào)用時(shí)是引用傳遞,在使用“=”賦值時(shí)也采用引用傳遞。
在實(shí)際開發(fā)中,經(jīng)常會(huì)遇到從某個(gè)已有的對(duì)象A創(chuàng)建出另外一個(gè)與A具有相同狀態(tài)的對(duì)象B,并且對(duì)B的修改不會(huì)影響到A的狀態(tài)。
例如要實(shí)現(xiàn) clone一個(gè)對(duì)象實(shí)例,在Java語(yǔ)言中,僅僅通過(guò)簡(jiǎn)單的賦值操作顯然無(wú)法達(dá)到這個(gè)目的。
Java提供了一個(gè)簡(jiǎn)單有效的clone()方法來(lái)滿足這個(gè)需求。Java中的所有類默認(rèn)都繼承自O(shè)bject類,而Object類中提供了一個(gè)clone()方法。這個(gè)方法的作用是返回一個(gè)Object對(duì)象的復(fù)制。這個(gè)復(fù)制函數(shù)返回的是一個(gè)新的對(duì)象而不是一個(gè)引用。實(shí)現(xiàn) clone 的基本實(shí)現(xiàn)步驟如下:
實(shí)現(xiàn)clone的類首先需要實(shí)現(xiàn)Cloneable接口。Cloneable接口實(shí)質(zhì)上是一個(gè)標(biāo)識(shí)接口,沒(méi)有任何接口方法。
在類中重寫Object類中的clone()方法。
在clone方法中調(diào)用super.clone()。無(wú)論clone類的繼承結(jié)構(gòu)是什么,super.clone()都會(huì)直接或間接調(diào)用java.lang.Object類的clone()方法。
把淺復(fù)制的引用指向原型對(duì)象新的克隆體。
實(shí)例操作如下:
測(cè)試用例如下

輸出結(jié)果如下:

在C++語(yǔ)言中,當(dāng)開發(fā)人員自定義復(fù)制構(gòu)造函數(shù)時(shí),會(huì)存在淺復(fù)制與深復(fù)制之分。Java語(yǔ)言在重載clone()方法時(shí)也存在同樣的問(wèn)題,當(dāng)類中只有一些基本的數(shù)據(jù)類型時(shí),采用上述方法就可以了,但是當(dāng)類中包含了一些對(duì)象時(shí),就需要用到深復(fù)制了,實(shí)現(xiàn)方法是在對(duì)對(duì)象調(diào)用clone()方法完成復(fù)制后,接著對(duì)對(duì)象中的非基本類型的屬性也調(diào)用clone()方法完成深復(fù)制。
那么在實(shí)際開發(fā)中,如何選擇使用哪種復(fù)制方式呢?首先,檢查類有無(wú)非基本類型(即對(duì)象)的數(shù)據(jù)成員。若沒(méi)有,則返回super.clone()即可;若有,確保類中包含的所有非基本類型的成員變量都實(shí)現(xiàn)了深復(fù)制。
實(shí)例操作如下:

完畢