摘要:不合規(guī)的代碼示例合規(guī)解決方案參閱復(fù)制構(gòu)造函數(shù)與克隆也可以參閱應(yīng)該實(shí)現(xiàn)克隆覆蓋的類應(yīng)為并調(diào)用下面為引文翻譯談設(shè)計(jì)與作者的對(duì)話,作者首次在上發(fā)表,年月日復(fù)制構(gòu)造函數(shù)與克隆在你的書中,你建議使用復(fù)制構(gòu)造函數(shù)而不是實(shí)現(xiàn)和編寫。
今天在用 sonar 審核代碼, 偶然看到下面的提示:
關(guān)于這個(gè)的提示大意是:
“克隆”不應(yīng)該被覆蓋, 屬壞味道, 阻斷型錯(cuò)誤
約書亞?布洛赫表示,許多人在 Java 中對(duì) clone 方法 和 Cloneable 接口存在誤解,很大程度上是因?yàn)橹貙?clone 方法的規(guī)則很棘手, 且出錯(cuò)難以糾正。
Object 的 clone 方法非常棘手。它基于屬性復(fù)制,而且是“超語(yǔ)言”。它創(chuàng)建一個(gè)對(duì)象而不調(diào)用構(gòu)造函數(shù)。無(wú)法保證它保留構(gòu)造函數(shù)創(chuàng)建的不變量。多年來(lái),在 Sun 公司內(nèi)外都存在許多錯(cuò)誤,這源于這樣一個(gè)事實(shí),即如果你只是反復(fù)調(diào)用 super.clone 直到克隆了一個(gè)對(duì)象,那么你就擁有了一個(gè)淺層的對(duì)象副本。克隆通常與正在克隆的對(duì)象共享狀態(tài)。如果該狀態(tài)是可變的,則您沒(méi)有兩個(gè)獨(dú)立的對(duì)象。如果您修改一個(gè),另一個(gè)也會(huì)更改。突然之間,你會(huì)得到隨機(jī)行為。
所以, 應(yīng)該使用復(fù)制構(gòu)造函數(shù)或復(fù)制工廠。
clone 無(wú)論是否實(shí)現(xiàn) Cloneable 接口,此規(guī)則在被覆蓋時(shí)都會(huì)引發(fā)問(wèn)題。
不合規(guī)的代碼示例
public class MyClass { // ... public Object clone() { // Noncompliant //... } }
合規(guī)解決方案
public class MyClass { // ... MyClass (MyClass source) { //... } }
參閱
《復(fù)制構(gòu)造函數(shù)與克隆》
也可以參閱
S2157 - “Cloneables”應(yīng)該實(shí)現(xiàn)“克隆”
S1182 - 覆蓋“clone”的類應(yīng)為“Cloneable”并調(diào)用“super.clone()”
下面為引文翻譯
Josh Bloch 談設(shè)計(jì)
與《Effective Java》作者的對(duì)話,Josh Bloch
作者 Bill Venners
首次在JavaWorld上發(fā)表,2002年1月4日
Bill Venners: 在你的書中,你建議使用復(fù)制構(gòu)造函數(shù)而不是實(shí)現(xiàn)Cloneable和編寫clone。你能詳細(xì)說(shuō)明嗎?
Josh Bloch:如果你已經(jīng)閱讀了我的書中關(guān)于克隆的章節(jié),特別是如果你看得仔細(xì)的話,你就會(huì)知道我認(rèn)為克隆已經(jīng)完全壞掉的東西。有一些設(shè)計(jì)缺陷,其中最大的一個(gè)是 Cloneable 接口沒(méi)有 clone方法。這意味著它根本不起作用:實(shí)現(xiàn)了 Cloneable 接口并不說(shuō)明你可以用它做什么。相反,它說(shuō)明了內(nèi)部可能做些什么。它說(shuō)如果通過(guò)super.clone 反復(fù)調(diào)用它最終調(diào)用 Object 的 clone 方法,這個(gè)方法將返回原始的屬性副本。
但它沒(méi)有說(shuō)明你可以用一個(gè)實(shí)現(xiàn) Cloneable 接口的對(duì)象做什么,這意味著你不能做多態(tài) clone 操作。如果我有一個(gè) Cloneable 數(shù)組,你會(huì)認(rèn)為我可以運(yùn)行該數(shù)組并克隆每個(gè)元素以制作數(shù)組的深層副本,但不能。你不能強(qiáng)制轉(zhuǎn)換對(duì)象為 Cloneable 接口并調(diào)用 clone 方法,因?yàn)?Cloneable 沒(méi)有public clone 方法,Object 類也沒(méi)有。如果您嘗試強(qiáng)制轉(zhuǎn)換 Cloneable 并調(diào)用該 clone 方法,編譯器會(huì)說(shuō)您正在嘗試在對(duì)象上調(diào)用受保護(hù)的clone方法。
事實(shí)的真相是,您不通過(guò)實(shí)施 Cloneable 和提供 clone 除復(fù)制能力之外的公共方法為您的客戶提供任何能力。如果您提供具有不同名稱的copy操作, 怎么也不次于去實(shí)現(xiàn) Cloneable 接口。這基本上就是你用復(fù)制構(gòu)造函數(shù)做的事情。復(fù)制構(gòu)造方法有幾個(gè)優(yōu)點(diǎn),我在本書中有討論。一個(gè)很大的優(yōu)點(diǎn)是可以使副本具有與原始副本不同的實(shí)現(xiàn)。例如,您可以將一個(gè) LinkedList 復(fù)制到 ArrayList。
Object 的 clone 方法是非常棘手的。它基于屬性復(fù)制,而且是“超語(yǔ)言”。它創(chuàng)建一個(gè)對(duì)象而不調(diào)用構(gòu)造函數(shù)。無(wú)法保證它保留構(gòu)造函數(shù)建立的不變量。多年來(lái),在Sun內(nèi)外存在許多錯(cuò)誤,這源于這樣一個(gè)事實(shí),即如果你只是super.clone 反復(fù)調(diào)用鏈直到你克隆了一個(gè)對(duì)象,那么你就擁有了一個(gè)淺層的對(duì)象副本。克隆通常與正在克隆的對(duì)象共享狀態(tài)。如果該狀態(tài)是可變的,則您沒(méi)有兩個(gè)獨(dú)立的對(duì)象。如果您修改一個(gè),另一個(gè)也會(huì)更改。突然之間,你會(huì)得到隨機(jī)行為。
我使用的東西很少實(shí)現(xiàn) Cloneable。我經(jīng)常提供實(shí)現(xiàn)類的 clone 公共方法,僅是因?yàn)槿藗兤谕小N覜](méi)有抽象類實(shí)現(xiàn) Cloneable,也沒(méi)有接口擴(kuò)展它,因?yàn)槲也粫?huì)將實(shí)現(xiàn)的負(fù)擔(dān) Cloneable 放在擴(kuò)展(或?qū)崿F(xiàn))抽象類(或接口)的所有類上。這是一個(gè)真正的負(fù)擔(dān),幾乎沒(méi)有什么好處。
Doug Lea 走得更遠(yuǎn)。他告訴我 clone 除了復(fù)制數(shù)組之外他不再使用了。您應(yīng)該使用 clone 復(fù)制數(shù)組,因?yàn)檫@通常是最快的方法。但 Doug 的類根本就不再實(shí)施 Cloneable了。他放棄了。而且我認(rèn)為這并非不合理。
這是一個(gè)恥辱, Cloneable 接口壞掉了,但它發(fā)生了。最初的 Java API在緊迫的期限內(nèi)完成,以滿足市場(chǎng)窗口收緊的需求。最初的 Java 團(tuán)隊(duì)做了不可思議的工作,但并非所有的 API 都是完美的。 Cloneable 是一個(gè)弱點(diǎn),我認(rèn)為人們應(yīng)該意識(shí)到它的局限性。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73848.html
摘要:嘻嘻大功告成計(jì)劃完美實(shí)現(xiàn)參考文獻(xiàn)樂(lè)柔嘴巴反向代理學(xué)習(xí)及實(shí)例筆記利用的反向代理克隆生成鏡像網(wǎng)站中間人攻擊原作者的原始游戲頁(yè)面上國(guó)人搬運(yùn)的開源鏡像特別致謝執(zhí)著的少年 先前在某個(gè)Q群里有位網(wǎng)友發(fā)了個(gè)鏈接,一點(diǎn)進(jìn)去,發(fā)現(xiàn)是個(gè)極度讓人耳目一新的初音未來(lái)音樂(lè)網(wǎng)頁(yè)游戲。 為了讓有幸看到這篇文章的看官也來(lái)體會(huì)下本人第一次玩時(shí)的激動(dòng),拋個(gè)鏈接——樂(lè)柔嘴巴。鏈接的具體地址是blog.eunji.cn/m...
摘要:嘻嘻大功告成計(jì)劃完美實(shí)現(xiàn)參考文獻(xiàn)樂(lè)柔嘴巴反向代理學(xué)習(xí)及實(shí)例筆記利用的反向代理克隆生成鏡像網(wǎng)站中間人攻擊原作者的原始游戲頁(yè)面上國(guó)人搬運(yùn)的開源鏡像特別致謝執(zhí)著的少年 先前在某個(gè)Q群里有位網(wǎng)友發(fā)了個(gè)鏈接,一點(diǎn)進(jìn)去,發(fā)現(xiàn)是個(gè)極度讓人耳目一新的初音未來(lái)音樂(lè)網(wǎng)頁(yè)游戲。 為了讓有幸看到這篇文章的看官也來(lái)體會(huì)下本人第一次玩時(shí)的激動(dòng),拋個(gè)鏈接——樂(lè)柔嘴巴。鏈接的具體地址是blog.eunji.cn/m...
摘要:嘻嘻大功告成計(jì)劃完美實(shí)現(xiàn)參考文獻(xiàn)樂(lè)柔嘴巴反向代理學(xué)習(xí)及實(shí)例筆記利用的反向代理克隆生成鏡像網(wǎng)站中間人攻擊原作者的原始游戲頁(yè)面上國(guó)人搬運(yùn)的開源鏡像特別致謝執(zhí)著的少年 先前在某個(gè)Q群里有位網(wǎng)友發(fā)了個(gè)鏈接,一點(diǎn)進(jìn)去,發(fā)現(xiàn)是個(gè)極度讓人耳目一新的初音未來(lái)音樂(lè)網(wǎng)頁(yè)游戲。 為了讓有幸看到這篇文章的看官也來(lái)體會(huì)下本人第一次玩時(shí)的激動(dòng),拋個(gè)鏈接——樂(lè)柔嘴巴。鏈接的具體地址是blog.eunji.cn/m...
摘要:自己寫一個(gè)程序來(lái)自動(dòng)生成測(cè)試數(shù)據(jù),因?yàn)槊總€(gè)個(gè)人作業(yè)的要求不一樣,自動(dòng)化框架無(wú)法對(duì)每種程序都生成測(cè)試數(shù)據(jù),目前只支持生成按規(guī)則生成隨機(jī)的字符串測(cè)試集。 作者:Grey...
閱讀 680·2021-09-30 09:47
閱讀 2873·2021-09-04 16:40
閱讀 856·2019-08-30 13:18
閱讀 3452·2019-08-29 16:22
閱讀 1555·2019-08-29 12:36
閱讀 586·2019-08-29 11:11
閱讀 1478·2019-08-26 13:47
閱讀 1132·2019-08-26 13:32