亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java對象克隆怎么實現

發布時間:2022-01-06 17:56:06 來源:億速云 閱讀:143 作者:iii 欄目:編程語言

本篇內容主要講解“Java對象克隆怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java對象克隆怎么實現”吧!

1. Overiew

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

2. How to Clone

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

Java代碼

protected native Object clone() throws CloneNotSupportedException;

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

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

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

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

Java代碼

1. x.clone() != x      will be true    2. x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements        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代碼

public interface Cloneable { }

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

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

Java代碼

public class DummyClone implements Cloneable{             public Object clone(){             DummyClone dc = null;             try {                 dc = (DummyClone)super.clone();             } catch (CloneNotSupportedException e) {                 e.printStackTrace();             }             return dc;         }     }

3. Shadow Clone

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

Java代碼

class ClassA {                  public int a;                  public void doubleA(){             a = a * 2;         }                  public ClassA(int aa){             this.a = aa;         }                  public String toString(){             return Integer.toString(a);         }     }         class ClassB implements Cloneable{                  public int b;                  public ClassA ca = new ClassA(11);                  public Object clone(){             ClassB cb = null;             try {                 cb = (ClassB)super.clone();             } catch (CloneNotSupportedException e) {                 e.printStackTrace();             }             return cb;         }     }         public class ClassC {                  public static void main(String[] args) {             ClassB cb = new ClassB();             cb.b = 222;             System.out.println("before clone : cb.b = " + cb.b);             System.out.println("before clone : cb.ca = " + cb.ca);                          //             ClassB cb2 = (ClassB)cb.clone();             cb2.b = 3333;             cb2.ca.doubleA();             System.out.println("========================");             System.out.println("after clone : cb.b = " + cb.b);             System.out.println("after clone : cb.ca = " + cb.ca);             System.out.println("========================");             System.out.println("after clone : cb2.b = " + cb2.b);             System.out.println("after clone : cb2.ca = " + cb2.ca);         }     }

輸出結果如下:

Java代碼

before clone : cb.b = 222    before clone : cb.ca = 11    ========================     after clone : cb.b = 222    after clone : cb.ca = 22    ========================     after clone : cb2.b = 3333    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代碼

class ClassA implements Cloneable{                  public int a;                  public void doubleA(){             a = a * 2;         }                  public ClassA(int aa){             this.a = aa;         }                  public String toString(){             return Integer.toString(a);         }                  public Object clone(){             ClassA ca = null;             try {                 ca = (ClassA)super.clone();             } catch (CloneNotSupportedException e) {                 e.printStackTrace();             }             return ca;         }     }         class ClassB implements Cloneable{                  public int b;                  public ClassA ca = new ClassA(11);                  public Object clone(){             ClassB cb = null;             try {                 cb = (ClassB)super.clone();             } catch (CloneNotSupportedException e) {                 e.printStackTrace();             }             cb.ca = (ClassA)ca.clone();             return cb;         }     }         public class ClassC {                  public static void main(String[] args) {             ClassB cb = new ClassB();             cb.b = 222;             System.out.println("before clone : cb.b = " + cb.b);             System.out.println("before clone : cb.ca = " + cb.ca);                          //             ClassB cb2 = (ClassB)cb.clone();             cb2.b = 3333;             cb2.ca.doubleA();             System.out.println("========================");             System.out.println("after clone : cb.b = " + cb.b);             System.out.println("after clone : cb.ca = " + cb.ca);             System.out.println("========================");             System.out.println("after clone : cb2.b = " + cb2.b);             System.out.println("after clone : cb2.ca = " + cb2.ca);         }     }

輸出結果:

Java代碼

before clone : cb.b = 222    before clone : cb.ca = 11    ========================     after clone : cb.b = 222    after clone : cb.ca = 11    ========================     after clone : cb2.b = 3333    after clone : cb2.ca = 22

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

到此,相信大家對“Java對象克隆怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兰西县| 东丰县| 韩城市| 湖北省| 民乐县| 清涧县| 庆云县| 大姚县| 德兴市| 马边| 嘉荫县| 甘谷县| 朔州市| 磐石市| 苍山县| 绵竹市| 清水县| 中卫市| 呈贡县| 榆中县| 承德市| 临潭县| 汽车| 宜君县| 荣昌县| 蕉岭县| 济南市| 邢台市| 玉门市| 丹江口市| 溆浦县| 嘉祥县| 平湖市| 高尔夫| 拉孜县| 牙克石市| 广安市| 麦盖提县| 阿克| 张家口市| 郧西县|