在面試中大家可能會(huì)被問(wèn)到關(guān)于Clone的相關(guān)知識(shí)风题,經(jīng)過(guò)分析和研究總算把Clone理解了。不過(guò)只是個(gè)人的觀點(diǎn)晌砾,大家不喜歡千萬(wàn)別噴攀甚。那我們來(lái)看一下平時(shí)的工作中Clone機(jī)制是如何工作的?
1. Clone和Copy
假設(shè)現(xiàn)在有一個(gè)User對(duì)象馁启,User u1=new User(“U1001”,“Jason”,25)驾孔,通
常我們會(huì)有這樣的賦值User u2=u1,這個(gè)時(shí)候只是簡(jiǎn)單了copy了一下reference惯疙,u2和u1都指向內(nèi)存中同一個(gè)object翠勉,這樣u2或者u1的一個(gè)操作都可能影響到對(duì)方。打個(gè)比方霉颠,如果我們通過(guò)u2.setAge()方法改變了Age域的值对碌,那么u1通過(guò)getAge()方法得到的就是修改之后的Age域的值,顯然這不是我們?cè)敢饪吹降妮镔恕N覀兿M玫絬1的一個(gè)精確拷貝朽们,同時(shí)兩者互不影響,這時(shí)候我們就可以使用Clone來(lái)滿足我們的需求诉位。User u2=u1.clone()骑脱,這時(shí)會(huì)生成一個(gè)新的User對(duì)象,并且和u1具有相同的屬性值和方法苍糠。
2. Shallow Clone和Deep Clone
Clone是如何完成的呢叁丧?Object在對(duì)某個(gè)對(duì)象實(shí)施Clone時(shí)對(duì)其是一無(wú)所知的,它僅僅是簡(jiǎn)單地執(zhí)行域?qū)τ虻腸opy岳瞭,這就是Shallow Clone拥娄。這樣,問(wèn)題就來(lái)了咯瞳筏,以User為例条舔,它里面有一個(gè)域birthday不是基本型別的變量,而是一個(gè)reference變量乏矾,經(jīng)過(guò)Clone之后就會(huì)產(chǎn)生一個(gè)新的Date型別的reference孟抗,它和原始對(duì)象中對(duì)應(yīng)的域指向同一個(gè)Date對(duì)象,這樣克隆類(lèi)就和原始類(lèi)共享了一部分信息钻心,而這樣顯然是不利的凄硼,過(guò)程下圖所示:
這個(gè)時(shí)候我們就需要進(jìn)行deep Clone了,對(duì)那些非基本型別的域進(jìn)行特殊的處理捷沸,例如本例中的birthday摊沉。我們可以重新定義Clone方法,對(duì)birthday做特殊處理痒给,如下代碼所示:
3. Clone()方法的保護(hù)機(jī)制在Object中Clone()是被申明為protected的说墨,這樣做是有一定的道理的骏全,以User類(lèi)為例,通過(guò)申明為protected尼斧,就可以保證只有User類(lèi)里面才能“克隆”User對(duì)象姜贡,原理可以參考我前面關(guān)于public、protected棺棵、private的學(xué)習(xí)筆記楼咳。
4. Clone()方法的使用Clone()方法的使用比較簡(jiǎn)單,注意如下幾點(diǎn)即可:a. 什么時(shí)候使用shallow Clone烛恤,什么時(shí)候使用deep Clone母怜,這個(gè)主要看具體對(duì)象的域是什么性質(zhì)的,基本型別還是reference variableb. 調(diào)用Clone()方法的對(duì)象所屬的類(lèi)(Class)必須implements Clonable接口缚柏,否則在調(diào)用Clone方法的時(shí)候會(huì)拋出CloneNotSupportedException苹熏。
每個(gè)人的理解不一樣但是本質(zhì)是不變的,我們還是要不斷的去學(xué)習(xí)新的java只是币喧,那么好了轨域,免費(fèi)分享java學(xué)習(xí)的資料,需要的可以來(lái)加我微信領(lǐng)攘蝗瘛:tangniu520666,備注“4”扛邑,都是最新的怜浅,有需要的朋友可以來(lái)騷擾我。主要還是能過(guò)快速的學(xué)習(xí)java蔬崩,能夠趕上最后一班java學(xué)習(xí)IDE快車(chē)恶座。