成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java Object Cloning-Java對象克隆

開發 后端
基本的數據類型可以自動的實現深度的克隆,然而并不是所有的類都可以進行深度的克隆,就比如String類,其類定義為final,且沒有重載clone方法,我們就無法完成對String類的深度克隆。關于不可變對象的克隆,我們通常沒有必要去克隆。

1. Overiew

在實際編程中,我們經常會遇到這樣一個情景:有一個對象A,存在屬性方法,現在需要一個和A完全相同的新對象B,并且B的任何改動都不會影響到A中的值。那么,最常用的辦法就是對A進行克隆。

2. How to Clone

在java.lang.Object中有一個clone方法,該方法的簽名如下:

Java代碼

  1. protected native Object clone() throws CloneNotSupportedException;  

 

該方法返回一個Object實例的拷貝,該實例拷貝具有:

1)拷貝對象是一個新對象而不是一個原對象引用。

2)拷貝的對象中包含的是原有對象信息,而不是對象初始化的信息(也就是說,拷貝過程沒有調用構造函數)。

從第1條我們可以看出,拷貝的對象與原對象存在這樣一種關系:

Java代碼

  1. 1. x.clone() != x      will be true    
  2. 2. x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements        
  3. 3. x.clone().equals(x) will be true, but these are not absolute requirements    

 

要實現克隆,必須滿足一下三點:

1)類必須實現Cloneable接口

2)類必須重載Object類中的clone()方法

3)重載的clone()方法中,必須顯示調用super.clone()。

我們看一下Cloneable接口的定義:

Java代碼

  1. public interface Cloneable { }   

 

Cloneable接口是不包含任何方法的,僅僅表示一個標志(類似Serializable接口),而且這個標志也是針對Object類中clone()方法的,如果clone類沒有實現Cloneable接口,并調用了Object的clone()方法(也就是調用了super.Clone()方法),那么Object的clone()方法就會拋出CloneNotSupportedException異常。

按照要求,我們寫一個克隆類的小例子:

Java代碼

  1. public class DummyClone implements Cloneable{     
  2.     
  3.     public Object clone(){     
  4.         DummyClone dc = null;     
  5.         try {     
  6.             dc = (DummyClone)super.clone();     
  7.         } catch (CloneNotSupportedException e) {     
  8.             e.printStackTrace();     
  9.         }     
  10.         return dc;     
  11.     }     
  12. }   

 

3. Shadow Clone

首先,我們來看一個例子:ClassA沒有實現Cloneable接口。ClassB存在ClassA的實例,實現了Cloneable接口,并重載了clone方法。ClassC實例化一個ClassB對象,然后克隆一個對象。

Java代碼

  1. class ClassA {     
  2.          
  3.     public int a;     
  4.          
  5.     public void doubleA(){     
  6.         a = a * 2;     
  7.     }     
  8.          
  9.     public ClassA(int aa){     
  10.         this.a = aa;     
  11.     }     
  12.          
  13.     public String toString(){     
  14.         return Integer.toString(a);     
  15.     }     
  16. }     
  17.     
  18. class ClassB implements Cloneable{     
  19.          
  20.     public int b;     
  21.          
  22.     public ClassA ca = new ClassA(11);     
  23.          
  24.     public Object clone(){     
  25.         ClassB cb = null;     
  26.         try {     
  27.             cb = (ClassB)super.clone();     
  28.         } catch (CloneNotSupportedException e) {     
  29.             e.printStackTrace();     
  30.         }     
  31.         return cb;     
  32.     }     
  33. }     
  34.     
  35. public class ClassC {     
  36.          
  37.     public static void main(String[] args) {     
  38.         ClassB cb = new ClassB();     
  39.         cb.b = 222;     
  40.         System.out.println("before clone : cb.b = " + cb.b);     
  41.         System.out.println("before clone : cb.ca = " + cb.ca);     
  42.              
  43.         //     
  44.         ClassB cb2 = (ClassB)cb.clone();     
  45.         cb2.b = 3333;     
  46.         cb2.ca.doubleA();     
  47.         System.out.println("========================");     
  48.         System.out.println("after clone : cb.b = " + cb.b);     
  49.         System.out.println("after clone : cb.ca = " + cb.ca);     
  50.         System.out.println("========================");     
  51.         System.out.println("after clone : cb2.b = " + cb2.b);     
  52.         System.out.println("after clone : cb2.ca = " + cb2.ca);     
  53.     }     
  54. }    

 

輸出結果如下:

Java代碼

  1. before clone : cb.b = 222    
  2. before clone : cb.ca = 11    
  3. ========================     
  4. after clone : cb.b = 222    
  5. after clone : cb.ca = 22    
  6. ========================     
  7. after clone : cb2.b = 3333    
  8. after clone : cb2.ca = 22  

 

從結果我們看到,int類型的b被完全的克隆了,而ClassA類型的ca卻沒有被克隆。因為克隆后cb2對b的賦值不會影響原有cb中b的值,而調用cb2.ca.doubleA()方法后,對cb2.ca的改變同時改變了cb.ca,表明cb2.ca與cb.ca僅僅指向同一個對象的不同引用。從中可以看出,調用Object類中clone()方法產生的效果是:先在內存中開辟一塊和原始對象一樣的空間,然后原樣拷貝原始對象中的內容。對基本數據類型,這樣的操作是沒有問題的,但對非基本類型變量clone后的變量和原始對象中相應的變量指向的是同一個對象。

這就是影子克隆。影子克隆,并沒有完整的完成克隆,有時候這并不是我們想要的結果。我們有時需要,就像列子中調用cb2.ca.doubleA()方法時,不會對原對象產生改變,這時候我們就需要deep clone;

4. Deep Clone

要實現深度克隆,在上面的例子基礎上,我們只需要這樣修改即可:

Java代碼

  1. class ClassA implements Cloneable{     
  2.          
  3.     public int a;     
  4.          
  5.     public void doubleA(){     
  6.         a = a * 2;     
  7.     }     
  8.          
  9.     public ClassA(int aa){     
  10.         this.a = aa;     
  11.     }     
  12.          
  13.     public String toString(){     
  14.         return Integer.toString(a);     
  15.     }     
  16.          
  17.     public Object clone(){     
  18.         ClassA ca = null;     
  19.         try {     
  20.             ca = (ClassA)super.clone();     
  21.         } catch (CloneNotSupportedException e) {     
  22.             e.printStackTrace();     
  23.         }     
  24.         return ca;     
  25.     }     
  26. }     
  27.     
  28. class ClassB implements Cloneable{     
  29.          
  30.     public int b;     
  31.          
  32.     public ClassA ca = new ClassA(11);     
  33.          
  34.     public Object clone(){     
  35.         ClassB cb = null;     
  36.         try {     
  37.             cb = (ClassB)super.clone();     
  38.         } catch (CloneNotSupportedException e) {     
  39.             e.printStackTrace();     
  40.         }     
  41.         cb.ca = (ClassA)ca.clone();     
  42.         return cb;     
  43.     }     
  44. }     
  45.     
  46. public class ClassC {     
  47.          
  48.     public static void main(String[] args) {     
  49.         ClassB cb = new ClassB();     
  50.         cb.b = 222;     
  51.         System.out.println("before clone : cb.b = " + cb.b);     
  52.         System.out.println("before clone : cb.ca = " + cb.ca);     
  53.              
  54.         //     
  55.         ClassB cb2 = (ClassB)cb.clone();     
  56.         cb2.b = 3333;     
  57.         cb2.ca.doubleA();     
  58.         System.out.println("========================");     
  59.         System.out.println("after clone : cb.b = " + cb.b);     
  60.         System.out.println("after clone : cb.ca = " + cb.ca);     
  61.         System.out.println("========================");     
  62.         System.out.println("after clone : cb2.b = " + cb2.b);     
  63.         System.out.println("after clone : cb2.ca = " + cb2.ca);     
  64.     }     
  65. }    

 

輸出結果:

Java代碼

  1. before clone : cb.b = 222    
  2. before clone : cb.ca = 11    
  3. ========================     
  4. after clone : cb.b = 222    
  5. after clone : cb.ca = 11    
  6. ========================     
  7. after clone : cb2.b = 3333    
  8. after clone : cb2.ca = 22 

 

基本的數據類型可以自動的實現深度的克隆,然而并不是所有的類都可以進行深度的克隆,就比如String類,其類定義為final,且沒有重載clone方法,我們就無法完成對String類的深度克隆。關于不可變對象的克隆,我們通常沒有必要去克隆。

【編輯推薦】

  1. Java中傳值及引伸深度克隆的思考
  2. 淺析Java中的深拷貝與淺拷貝
  3. 對Java本身API庫的擴充:Jython庫列表
  4. JAVA 對象拷貝
  5. Java新手進階:細說引用類型
責任編輯:金賀 來源: ITEYE博客
相關推薦

2018-04-03 13:10:27

Java對象克隆

2010-10-28 13:06:45

Java克隆特性

2011-06-28 11:27:19

java克隆對象

2021-06-03 10:00:47

JavaScript 前端數克隆對象

2010-02-01 16:14:33

Python PySt

2011-03-04 09:25:51

Java序列化

2010-01-22 13:28:13

VB.NET對象克隆

2010-01-25 11:28:59

2020-12-01 15:00:20

Java 基礎

2010-02-01 16:07:23

PyStringObj

2010-10-09 09:56:51

JavaScriptObject對象

2010-01-15 16:59:52

VB.NET對象克隆

2024-01-05 07:46:15

JS克隆對象JSON

2014-06-19 11:42:36

克隆虛擬化應用程序

2009-11-30 16:40:38

PHP object對

2024-11-29 08:45:33

2011-08-17 09:27:55

FlexJava

2022-01-15 10:01:15

Javascript 高階函數前端

2021-11-29 09:38:12

設計模式對象池模式Object Pool

2021-09-03 10:00:00

JavaScript迭代對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩一区二区在线播放 | 99精品久久久久久中文字幕 | 亚洲九九 | 亚洲激情网站 | 亚洲欧美一区二区三区国产精品 | 色婷婷综合久久久中字幕精品久久 | 亚洲精品久久久9婷婷中文字幕 | 精品欧美一区二区三区久久久 | 成人在线免费观看 | 日韩区 | 婷婷久久五月天 | 久久久久久成人网 | 午夜大片 | 亚洲精品一二三区 | 国产日本精品视频 | 亚洲444kkkk在线观看最新 | 久草网在线视频 | 亚洲成网 | 亚洲精品一区在线观看 | 国产97人人超碰caoprom | 国产一区二区久久 | 亚洲精品自在在线观看 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 亚洲欧美在线视频 | 中文字幕精品一区 | 成人在线观看欧美 | 午夜天堂精品久久久久 | 日韩欧美国产精品一区二区三区 | 国产在线视频一区二区董小宛性色 | 国产精品美女久久久av超清 | 性色视频 | 欧美一级免费片 | 欧美精品成人影院 | 日韩有码一区 | 欧洲亚洲精品久久久久 | 日韩中文字幕一区 | 999www视频免费观看 | 日韩精品极品视频在线观看免费 | 国产日韩中文字幕 | 午夜资源 | 国产成人午夜精品影院游乐网 |