我不知道的事——深克隆和淺克隆



??????
?????? 推薦一部好電影《致命魔術》。(此處為植入廣告)
?????? 推薦理由:涉及人性。畫面不錯,劇情跌宕,亦魔亦幻(此處的”魔“為魔術的”魔“)。雖然女豬腳不盡如人意,但是男豬腳比較帥。而且看完后有利于理解克隆,當然理解了克隆也利于觀影!

?????? 首先,簡單客觀地解釋下幾個關鍵的名詞(我們約定A表示原來的對象,P表示A引用的對象;AC表示克隆后的A對象):
?????? 淺克隆:復制克隆對象的基本信息及其對其他對象的引用。在改變AC對象的P對象時,那么也會改變A對象的P對象。
?????? 深克隆:深克隆也會復制對象的基本信息以及其對其他對象的引用,但是,改變AC對象的引用P對象時,不會引起A對象的P對象。

?????? 從前面淺克隆的定義上看,改變AC的P就能改變A的P,這樣顯得這種克隆更加像深克隆(都刨到別人祖墳了,夠深的!)。但是,換個角度來看,這種克隆只是淺顯的將一個對象拷貝出來了,并沒有真正的去對這個對象進行深入地剖析,即沒有剝離兩者之間的依賴,使得A和AC更像一個對象的不同命名,因此,反而顯得淺顯了。深克隆的技術含量也較之淺克隆高點。
?????? 為了方便理解,我將淺克隆形象化為一對連體雙胞胎,而將深克隆形象化為一對同卵雙胞胎;或者也可將淺克隆理解為鏡像,而深克隆則是復制了一個真正具有獨立行為能力的實體。
?????? 下面詳細對它們進行闡述:
?????? 克隆
?????? 實現克隆的類都必須實現Cloneable接口,而且一般需要重寫Object類里的clone()方法。我們首先看看Object類中對clone()方法的注釋與聲明:

Java代碼 ?收藏代碼
  1. /**?
  2. ?????*?Creates?and?returns?a?copy?of?this?object.??The?precise?meaning?
  3. ?????*?of?"copy"?may?depend?on?the?class?of?the?object.?The?general?
  4. ?????*?intent?is?that,?for?any?object?{@code?x},?the?expression:?
  5. ?????*?<blockquote>?
  6. ?????*?<pre>?
  7. ?????*?x.clone()?!=?x</pre></blockquote>?
  8. ?????*?will?be?true,?and?that?the?expression:?
  9. ?????*?<blockquote>?
  10. ?????*?<pre>?
  11. ?????*?x.clone().getClass()?==?x.getClass()</pre></blockquote>?
  12. ?????*?will?be?{@code?true},?but?these?are?not?absolute?requirements.?
  13. ?????*?While?it?is?typically?the?case?that:?
  14. ?????*?<blockquote>?
  15. ?????*?<pre>?
  16. ?????*?x.clone().equals(x)</pre></blockquote>?
  17. ?????*?will?be?{@code?true},?this?is?not?an?absolute?requirement.?
  18. ?????*?<p>?
  19. ?????*?By?convention,?the?returned?object?should?be?obtained?by?calling?
  20. ?????*?{@code?super.clone}.??If?a?class?and?all?of?its?superclasses?(except?
  21. ?????*?{@code?Object})?obey?this?convention,?it?will?be?the?case?that?
  22. ?????*?{@code?x.clone().getClass()?==?x.getClass()}.?
  23. ?????*?<p>?
  24. ?????*?By?convention,?the?object?returned?by?this?method?should?be?independent?
  25. ?????*?of?this?object?(which?is?being?cloned).??To?achieve?this?independence,?
  26. ?????*?it?may?be?necessary?to?modify?one?or?more?fields?of?the?object?returned?
  27. ?????*?by?{@code?super.clone}?before?returning?it.??Typically,?this?means?
  28. ?????*?copying?any?mutable?objects?that?comprise?the?internal?"deep?structure"?
  29. ?????*?of?the?object?being?cloned?and?replacing?the?references?to?these?
  30. ?????*?objects?with?references?to?the?copies.??If?a?class?contains?only?
  31. ?????*?primitive?fields?or?references?to?immutable?objects,?then?it?is?usually?
  32. ?????*?the?case?that?no?fields?in?the?object?returned?by?{@code?super.clone}?
  33. ?????*?need?to?be?modified.?
  34. ?????*?<p>?
  35. ?????*?The?method?{@code?clone}?for?class?{@code?Object}?performs?a?
  36. ?????*?specific?cloning?operation.?First,?if?the?class?of?this?object?does?
  37. ?????*?not?implement?the?interface?{@code?Cloneable},?then?a?
  38. ?????*?{@code?CloneNotSupportedException}?is?thrown.?Note?that?all?arrays?
  39. ?????*?are?considered?to?implement?the?interface?{@code?Cloneable}?and?that?
  40. ?????*?the?return?type?of?the?{@code?clone}?method?of?an?array?type?{@code?T[]}?
  41. ?????*?is?{@code?T[]}?where?T?is?any?reference?or?primitive?type.?
  42. ?????*?Otherwise,?this?method?creates?a?new?instance?of?the?class?of?this?
  43. ?????*?object?and?initializes?all?its?fields?with?exactly?the?contents?of?
  44. ?????*?the?corresponding?fields?of?this?object,?as?if?by?assignment;?the?
  45. ?????*?contents?of?the?fields?are?not?themselves?cloned.?Thus,?this?method?
  46. ?????*?performs?a?"shallow?copy"?of?this?object,?not?a?"deep?copy"?operation.?
  47. ?????*?<p>?
  48. ?????*?The?class?{@code?Object}?does?not?itself?implement?the?interface?
  49. ?????*?{@code?Cloneable},?so?calling?the?{@code?clone}?method?on?an?object?
  50. ?????*?whose?class?is?{@code?Object}?will?result?in?throwing?an?
  51. ?????*?exception?at?run?time.?
  52. ?????*?
  53. ?????*?@return?????a?clone?of?this?instance.?
  54. ?????*?@exception??CloneNotSupportedException??if?the?object's?class?does?not?
  55. ?????*???????????????support?the?{@code?Cloneable}?interface.?Subclasses?
  56. ?????*???????????????that?override?the?{@code?clone}?method?can?also?
  57. ?????*???????????????throw?this?exception?to?indicate?that?an?instance?cannot?
  58. ?????*???????????????be?cloned.?
  59. ?????*?@see?java.lang.Cloneable?
  60. ?????*/??
  61. ????protected?native?Object?clone()?throws?CloneNotSupportedException;??

?????? 雖然過長,但是我覺得還是很有必要看看的。從前面的注釋中可以看出:x.clone() != x 但是 x.clone().getClass() == x.getClass() 。這可以看成克隆的精確描述。從x.clone() != x 看,覺得這個鏡像也不簡單,鏡子里面的世界和鏡子外面的世界原來也不是同一個,開始有一點魔幻的味道了。注釋里還有一句話值得我們關注:Note that all arrays are considered to implement the interface? Cloneable and that the return type of the clone method of an array type T[] is T[] where T is any reference or primitive type.所有的數組都實現了Cloneable接口,返回的是一個數組類型。這個大家可以驗證一下,反正我驗證是有的。這段注釋里還有很多地方值得我們去研究(比如提到了深克隆和淺克隆),我都好不容易貼出來了,大家自己去看看吧!
?????? clone()方法會拋出CloneNotSupportedException,這是為什么呢?這是因為Object類沒有實現Cloneable接口。身為萬物之祖,Object也有很多不會的啊!

?????? 淺克隆
?????? 要想做到AC的屬性和A一樣其實并不難,最簡單的辦法就是AC = A;而且也能保證改變AC的P會引起A的P改變。這樣不就可以了嗎?為什么還要用克隆呢?你似乎忘了,在克隆里我們講過,AC和A需滿足兩個條件:x.clone() != x和x.clone().getClass() == x.getClass()。如果直接AC = A,很明顯AC == A返回的是true。至于具體原因就涉及到克隆的作用了,等會的克隆的用途會詳細說明。
?????? 淺克隆的實現并不難,下面看一個示例:

Java代碼 ?收藏代碼
  1. class?Sword{??
  2. ????????String?name;??
  3. ????????float?weight;??
  4. ????????public?Sword(String?name,?float?weight){??
  5. ????????????this.name?=?name;??
  6. ????????????this.weight?=?weight;??
  7. ????????}?//?end?constructor??
  8. ????}?//?end?class?Sword??
  9. ??????
  10. ????class?Hero?implements?Cloneable{??
  11. ????????String?name;??
  12. ????????int?energy;?//?hero的戰斗值??
  13. ????????Sword?s;??
  14. ????????public?Hero(String?name,?int?energy,?Sword?s){??
  15. ????????????this.name?=?name;??
  16. ????????????this.energy?=?energy;??
  17. ????????????this.s?=?s;??
  18. ????????}?//?end?constructor??
  19. ??????????
  20. ????????public?void?kill(){??
  21. ????????????System.out.println("戰斗值為"?+?energy?+?"的"?+?name?+?"揮動著重為"??
  22. ????????????????????+?s.weight?+?"斤的"?+?s.name?+?"要開殺戒了!");??
  23. ????????}?//?end?kill??
  24. ??????????
  25. ????????/**?
  26. ?????????*?重寫Object的clone方法。?
  27. ?????????*/??
  28. ????????public?Object?clone(){??
  29. ????????????Hero?h?=?null;??
  30. ????????????try?{??
  31. ????????????????h?=?(Hero)super.clone();??
  32. ????????????}?catch?(CloneNotSupportedException?e)?{??
  33. ????????????????e.printStackTrace();??
  34. ????????????}?//?end?try-catch??
  35. ????????????return?h;??
  36. ????????}?//?end?clone??
  37. ????}?//?end?class?Hero??
  38. ??????
  39. ????public?class?ShallowClone{??
  40. ????????/**?
  41. ?????????*?主函數。?
  42. ?????????*?@param?args?
  43. ?????????*/??
  44. ????????public?static?void?main(String[]?args)?{??
  45. ????????????//?聲明一個Sword對象??
  46. ????????????Sword?s?=?new?Sword("絕世好劍",?58.3f);??
  47. ????????????//?聲明一個Hero??
  48. ????????????Hero?h1?=?new?Hero("步驚云",?1000,?s);??
  49. ????????????h1.kill();??
  50. ????????????//?克隆??
  51. ????????????Hero?h2?=?(Hero)?h1.clone();??
  52. ????????????//?改變h2的s的一些屬性??
  53. ????????????h2.s.name?=?"草雉劍";??
  54. ????????????h2.s.weight?=?23.4f;??
  55. ????????????h1.kill();??
  56. ????????if(?!(h1?==?h2)){??
  57. ????????????System.out.println("從哲學的角度講:此時的"?+???
  58. ????????????????h1.name?+?"已經不是從前的"?+?h1.name?+?"了!");??
  59. ????????}else{??
  60. ????????????System.out.println("娃哈哈,我"?+?h1.name?+?"還是"?+?h1.name???????????????????+?"!");??
  61. ????????????}?//?end?if-else??
  62. ????????}?//?end?main?????
  63. ????}?//?end?class?ShallowClone??

?????? 這段代碼的運行結果是什么呢?請看:
???? ?????? 戰斗值為1000的步驚云揮動著重為58.3斤的絕世好劍要開殺戒了!
?????????? 戰斗值為1000的步驚云揮動著重為23.4斤的草雉劍要開殺戒了!
?????????? 從哲學的角度講:此時的步驚云已經不是從前的步驚云了!
?????? 是的,正如我們所說的h1的s對象的name和weight也改變了。而且其實現也是很簡單。當然對這一塊比較熟悉的朋友會非常氣憤地指出,這里有一些基本的常識錯誤:絕世好劍和草雉劍根本就不是這個重量,步驚云也得不到草雉劍!但是,("made in China".equals("everything is possible")) == true(支持國產,再次植入廣告!)。好吧,我們回到淺克隆,這里實現淺克隆的代碼相當簡單,直接super.clone()就可以了。
?????? 網上有一種說法,說淺克隆是不正確的克隆。我覺得不管正不正確,當我們要克隆的對象只有基本數據類型和String等屬性時,直接淺克隆就可以了。運用之妙,存乎一心!

?????? 深克隆
?????? 前面講了,深克隆就是將克隆的對象和原來的對象獨立開來。那么怎么實現呢?
?????? 在上面的代碼上修改了一點:

Java代碼 ?收藏代碼
  1. class?Sword?implements?Cloneable{??
  2. ????????String?name;??
  3. ????????float?weight;??
  4. ????????public?Sword(String?name,?float?weight){??
  5. ????????????this.name?=?name;??
  6. ????????????this.weight?=?weight;??
  7. ????????}?//?end?constructor??
  8. ????????public?Object?clone(){??
  9. ????????????try?{??
  10. ????????????????return?super.clone();??
  11. ????????????}?catch?(CloneNotSupportedException?e)?{??
  12. ????????????????e.printStackTrace();??
  13. ????????????}?//?end?try-catch??
  14. ????????????return?null;??
  15. ????????}?//?end?clone??
  16. ????}?//?end?class?Sword??
  17. ??
  18. ????class?Hero?implements?Cloneable{??
  19. ????????String?name;??
  20. ????????int?energy;?//?hero的戰斗值??
  21. ????????Sword?s;??
  22. ????????public?Hero(String?name,?int?energy,?Sword?s){??
  23. ????????????this.name?=?name;??
  24. ????????????this.energy?=?energy;??
  25. ????????????this.s?=?s;??
  26. ????????}?//?end?constructor??
  27. ????????public?void?kill(){??
  28. ????????????System.out.println("戰斗值為"?+?energy?+?"的"?+?name?+?"揮動著??????????????????重為"?+?s.weight?+?"斤的"?+?s.name?+?"要開殺戒了!");??
  29. ????????}?//?end?kill??
  30. ????????/**?
  31. ?????????*?重寫Object的clone方法。?
  32. ?????????*/??
  33. ????????public?Object?clone(){??
  34. ????????????Hero?h?=?null;??
  35. ????????????try?{??
  36. ????????????????h?=?(Hero)super.clone();??
  37. ????????????????h.s?=?(Sword)?s.clone();??
  38. ????????????}?catch?(CloneNotSupportedException?e)?{??
  39. ????????????????e.printStackTrace();??
  40. ????????????}?//?end?try-catch??
  41. ????????????return?h;??
  42. ????????}?//?end?clone??
  43. ????}?//?end?class?Hero??
  44. ??
  45. ????public?class?DeepClone{???
  46. ????????/**?
  47. ?????????*?主函數。?
  48. ????????*?@param?args?
  49. ????????*/??
  50. ????????public?static?void?main(String[]?args)?{??
  51. ????????????//?聲明一個Sword對象??
  52. ????????????Sword?s?=?new?Sword("絕世好劍",?58.3f);??
  53. ????????????//?聲明一個Hero??
  54. ????????????Hero?h1?=?new?Hero("步驚云",?1000,?s);??
  55. ????????????h1.kill();??
  56. ????????????//?克隆??
  57. ????????????Hero?h2?=?(Hero)?h1.clone();??
  58. ????????????//?改變h2的s的一些屬性??
  59. ????????????h2.s.name?=?"草雉劍";??
  60. ????????????h2.s.weight?=?23.4f;??
  61. ????????????h1.kill();??
  62. ????????????if(!?(h1?==?h2)){??
  63. ????????????????System.out.println("從哲學的角度講:此時的"?+???
  64. ????????????????????????h1.name?+?"已經不是從前的"?+?h1.name?+?"了!");??
  65. ????????????}else{??
  66. ????????????????System.out.println("娃哈哈,我"?+?h1.name?+?"還是"?+?h1.name?+?"!");??
  67. ????????????}?//?end?if-else??
  68. ????????}?//?end?main??
  69. ????}?//?end?class?DeepClone??

?????? 認真觀察就會發現,代碼的變動并不是很大,只是Sword類也實現了Cloneable接口,在Hero中也對hero對象的sword進行了克隆。這樣就實現了深克隆。那么這段代碼的結果是不是我們希望看到的呢:
?????????????? 戰斗值為1000的步驚云揮動著重為58.3斤的絕世好劍要開殺戒了!
?????????????? 戰斗值為1000的步驚云揮動著重為58.3斤的絕世好劍要開殺戒了!
?? ???????????? 從哲學的角度講:此時的步驚云已經不是從前的步驚云了!
?????? 看吧,h1并沒有因為克隆后的h2改變了s的name和weight而跟著發生了改變,圓滿完成了我們的預期目標。
?????? 關于深克隆還有另一種方式:使用Serializable。大家可以去關注一下,這里就不討論了。

?????? 克隆的用途
?????? 我們知道了深克隆和淺克隆,那么克隆到底有什么用呢?
?????? 答案很簡單:有需求就有市場。我們要克隆是因為我們需要一個和已知對象一樣的對象(這個我覺得看了《致命魔術》后肯定理解得更深)。當我們需要一個對象的副本但又不想影響原來的對象時,我們可以考慮使用克隆。
?????? 個人覺得克隆為程序員提供了對對象更加靈活的操縱力。我覺得大家在理解的基礎上然后提出自己的見解就可以了。

?????? 總結
?????? 最近看《Effective Java》,里面專門提到了:謹慎地覆蓋clone。而且里面也提到了用copy constructor(克隆構造器)或者copy factory(克隆工廠)更加地安全。網上有很多解說的,但是我覺得這個版本不錯,大家去看看吧:http://www.slideshare.net/fmshaon/effective-java-override-clone-method-judiciously

?????? 最后,還有一件事,《致命魔術》真的不錯!
?????? 晚安!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451590.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451590.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451590.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

服務器搭建

2019獨角獸企業重金招聘Python工程師標準>>> 最近弄了個阿里云的服務器&#xff0c;想在上面搞點東西&#xff0c;故要搭建一套環境。登錄linux&#xff0c;在終端輸入 uname -a 即列出linux的內核版本號。&#xff08;服務器網址&#xff1a;http://101.132.235.56…

mybatis內部類映射寫法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. B類是A類中的內部類。 2.  映射寫法&#xff1a; com.XXX.A$B , 注意A類和B類之間用 $ 表示內外關系&#xff0c;而不是常用的 …

集群,分布式,微服務的區別

參考文獻&#xff1a; 集群,分布式&#xff0c;微服務概念和區別理解 謝謝作者分享&#xff01;

Linux bash總結(一) 基礎部分(適合初學者學習和非初學者參考)

第一部分 bash簡介 —— 對bash進行簡要介紹 第二部分 bash示例和書寫流程 —— 以一個簡單的bash為例&#xff0c;說明書寫、執行bash的流程 第三部分 bash基礎語法 —— 本章內容比較多&#xff0c;主要介紹if...else...條件判斷&#xff0c;for循環等等。對于有編…

用 Python 語言來寫游戲

每個程序員差不多都是從計算機愛好者開始的&#xff0c;尤其是那些令人心醉神迷的電腦游戲&#xff0c;不僅造就了整個游戲產業&#xff0c;推動了計算機行業軟硬件的升級&#xff0c;而且吸引了大量的愛好者最終加入了游戲軟件開發的行業。騰訊、網易、盛大、完美時空等公司的…

各種操作系統簡介和功能分析

Windows 開發商 Microsoft Windows98/me Windows2000/XP Windows Server2003 Windows Vista Windows98/me是基于MS-DOS的混合的16/32位操作系統正慢慢的退出PC舞臺了,2000/X P以及Server2003都是基于WindowsNT的32位操作系統,XP/Server2003已經有64位版本了。 Vista是微軟最…

Cookie與Session的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 cookie機制 Cookies是服務器在本地機器上存儲的小段文本并隨每一個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mec…

python實現簡易工資管理系統(Salary Manage)源碼

一、需求&#xff1a; 1.導入文件讀取員工的信息和工資信息&#xff0c;最后將增加、刪除或修改的員工工資信息寫入原來的文件中 2.能夠實現員工工資信息的增刪改查 3.當增加和修改員工信息時用戶用空格分隔員工姓名和薪資 4.實現退出功能 二、思路 1.首先需要將包含有員工薪資…

python 的作用

print正常是要輸出到屏幕上&#xff0c;如果你希望輸出到其他地方比如文件&#xff0c;就需要使用>>來把輸出導向到文件。空格的目的是要區分關鍵詞&#xff0c;如果你輸入的是print>>&#xff0c;電腦會把它當成一個單詞&#xff0c;而無法知道是print函數。

操作系統內存管理

參考文獻&#xff1a; 20 張圖揭開內存管理的迷霧 感謝三太子敖丙分享&#xff01;

hexo github搭建博客常用的命令

這些命令你都用過嗎&#xff1f; npm install hexo -g #安裝 npm update hexo -g #升級 hexo init #初始化 hexo new "postName" #新建文章 hexo new page "pageName" #新建頁面 hexo generate #生成靜態頁面至public目錄 hexo server #開啟預覽訪問端口&a…

寫博客的好處,專家告訴你

把自己平時在做項目時和自己學習時的一些經驗和心得記錄下來。那樣&#xff0c;首先可以增強自己對知識點的理解&#xff1b;其次&#xff0c;以后再用到的話&#xff0c;可以很方便的查詢&#xff1b;最后&#xff0c;才是分享給大家&#xff0c;可以在用到這方面的知識的時候…

解決報錯:java.util.UnknownFormatConversionException: Conversion = ‘p‘

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. ssm框架下 報錯如題 2. 錯誤原因&#xff1a;我的情況是&#xff0c;代碼中實體屬性映射書寫和數據庫字段名字不一致。 選中位置數據…

JVM和JMM的區別

參考文獻&#xff1a; java中JVM和JMM之間的區別 感謝作者分享&#xff01;

[Java][網絡編程]服務端向客戶端發送信息

/*前置知識&#xff08;服務端&#xff09;1.首先要常見一個ServerSocket對象 服務端套接字&#xff0c;并且在服務端套接字里面確定需要使用的端口2.然后要創建一個Socket對象來接收ServerSocket的返回值。通常一個Socket對象對應一個客戶端/涉及到多個客戶端需要通過線程來解…

【Python】如何判斷一個字符串為空

#方法一 if oneString: print "not empty" else: print "empty" #方法二 if oneString "": print "empty" else: print "not empty"

LRU 實現緩存

LRU:Least Recently used 最近最少使用 1.使用LinkedHashMap實現 inheritance實現方式 繼承map類 可以使用Collections.synchronizedMap方式實現線程安全的操作 public class LruCache<K,V> extends LinkedHashMap<K,V> {private final int MAX_CACHE_SIZE;public …

使用vsftp作為集群的yum倉庫

地址規劃&#xff1a;vsftp服務器的地址為172.16.1.61使用的環境&#xff1a;[rootnfs01 scripts]# uname -a Linux nfs01 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux首先在yum服務器上掛載本地光盤mkdir /media/cdrom ;mount…

純做技術是自娛自樂 拋開技術做技術才是出路

短短一生不過數十載&#xff0c;對于很多人而言&#xff0c;作IT、作技術只是生命中的某一段&#xff0c;并非所有。而無論是換工作還是換行業&#xff0c;只是一種形式而已&#xff0c;最終我們追求的是成功、是榮譽、是收獲。于是在年輕的這幾年里&#xff0c;作為技術人員理…

TOAD連接Oracle數據庫失敗:OCI_INVALID_HANDLE解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. toad 連接Oracle數據庫連接失敗如圖&#xff1a; 2. 導致這個情況的前因&#xff1a;toad運行情況下&#xff0c;突然斷電。 3. 解決…