91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

如何解析Java語言的對象克隆特性

發布時間:2021-11-20 18:07:02 來源:億速云 閱讀:172 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關如何解析Java語言的對象克隆特性,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

在Java中傳值及引伸深度克隆的思考中,我們講過引申到克隆技術Java中的所有對象都是Object類的子類。我們知道,Java是純面向對象的程序設計語言。Java里,所有的類的***父類都是java.lang.Object類,也就是說,如果一個類沒有顯示 申明繼承關系,它的父類默認就是java.lang.Object。

有一個很簡單的方法可以證明這一點,我們寫一個Test類,如下:

public class Test {       public void someMethod() {           super.clone();       }   }

里面調用了super.clone(),編譯時并不報錯。其實clone()方法為java.lang.Object類提供的一個 protected型方法。

對象克隆

本文通過介紹java.lang.Object#clone()方法來說明Java語言的對象克隆特性。

java.lang.Object#clone()方法由java.lang.Object加以實現,主要對對象本身加以克隆。

首先我們看看下面的例子:

public class TestClone {       public static void main(String[] args) {           MyClone myClone1 = new MyClone("clone1");                     MyClone myClone2 = (MyClone)myClone1.clone();                     if (myClone2 != null) {               System.out.println(myClone2.getName());               System.out.println("myClone2 equals myClone1: " + myClone2.equals(myClone1));           } else {               System.out.println("Clone Not Supported");           }       }   }   class MyClone {       private String name;       public MyClone(String name) {           this.name = name;       }             public String getName() {           return name;       }       public void setName(String name) {           this.name = name;       }             public Object clone() {           try {               return super.clone();           } catch (CloneNotSupportedException e) {               return null;           }       }

編譯執行TestClone,打印出:

C:\clone>javac *.java   C:\clone>java TestClone   Clone Not Supported   C:\clone>

說明MyClone#clone()方法調用super.clone()時拋出了CloneNotSupportedException異常,不支持克隆。

為什么父類java.lang.Object里提供了clone()方法,卻不能調用呢?

原來,Java語言雖然提供了這個方法,但考慮到安全問題, 一方面將clone()訪問級別設置為protected型,以限制外部類訪問;

另一方面,強制需要提供clone功能的子類實現java.lang.Cloneable接口,在運行期,JVM會檢查調用clone()方法的 類,如果該類未實現java.lang.Cloneable接口,則拋出CloneNotSupportedException異常。

java.lang.Cloneable接口是一個空的接口,沒有申明任何屬性與方法。該接口只是告訴JVM,該接口的實現類需要開放“克隆”功能。

我們再將MyClone類稍作改變,讓其實現Cloneable接口:

class MyClone implements Cloneable {       ...//其余不做改變   }    編譯執行TestClone,打印出:    C:\clone>javac *.java   C:\clone>java TestClone   clone1   myClone2 equals myClone1: false   C:\clone>

根據結果,我們可以發現:

1,myClone1.clone()克隆了跟myClone1具有相同屬性值的對象

2,但克隆出的對象myClone2跟myClone1不是同一個對象(具有不同的內存空間)

小結

如果要讓一個類A提供克隆功能,該類必須實現java.lang.Cloneable接口,并重載 java.lang.Object#clone()方法。

public class A extends Cloneable {       public Object clone() {           try {               return super.clone();           } catch (CloneNotSupportedException e) {               //throw (new InternalError(e.getMessage()));               return null;           }       }   }

對象的深層次克隆

上例說明了怎么樣克隆一個具有簡單屬性(String,int,boolean等)的對象。

但如果一個對象的屬性類型是List,Map,或者用戶自定義的其他類時,克隆行為是通過怎樣的方式進行的?

很多時候,我們希望即使修改了克隆后的對象的屬性值,也不會影響到原對象,這種克隆我們稱之為對象的深層次克隆。怎么樣實現對象的深層次克隆呢?

驗證對象的克隆方式

為了驗證對象的克隆方式,我們對上面的例子加以改進,如下(為了節省篇幅,我們省略了setter與getter方法):

public class TestClone {       public static void main(String[] args) {           //為克隆對象設置值            MyClone myClone1 = new MyClone("clone1");            myClone1.setBoolValue(true);            myClone1.setIntValue(100);                     //設置List值            List <Element>listValue = new ArrayList<Element>();            listValue.add(new Element("ListElement1"));            listValue.add(new Element("ListElement2"));            listValue.add(new Element("ListElement3"));            myClone1.setListValue(listValue);                     //設置Element值            Element element1 = new Element("element1");            myClone1.setElement(element1);                               //克隆            MyClone myClone2 = (MyClone)myClone1.clone();                     if (myClone2 != null) {                             //簡單屬性                System.out.println("myClone2.name=" + myClone2.getName()                        + " myClone2.boolValue=" + myClone2.isBoolValue()                        + " myClone2.intValue=" + myClone2.getIntValue() );                             //復合屬性(List<Element>與Element)                List clonedList = myClone2.getListValue();                Element element2 = myClone2.getElement();                              System.out.println("myClone2.listValue.size():" + clonedList.size());                System.out.println("myClone2.element.equals(myClone1.element):" + element2.equals(element1));                System.out.println("myClone2.element.name:" + element2.getName());                             //下面我們測試一下myClone2.element是否等于myClone1.element               //以及myClone2.listValue是否等于myClone1.listValue               //為此,我們修改myClone2.element與myClone2.listValue,如果myClone1的相應值也跟著被修改了,則它們引用 的是同一個內存空間的變量,我們認為它們相等                              clonedList.add("ListElement4");                              System.out.println("myClone1.listValue.size():" + listValue.size());                              element2.setName("Element2");                System.out.println("myClone1.element.name:" + element1.getName());                          } else {                System.out.println("Clone Not Supported");            }                         }    }     class MyClone implements Cloneable {       private int intValue;       private boolean boolValue;       private String name;       private List <Element>listValue;       private Element element;        public MyClone(String name) {            this.name = name;        }         ...//setter與getter方法(略)   }    class Element implements Cloneable   {       private String name;             public Element (String name) {            this.name = name;        }         ...//setter與getter方法(略)   }

編譯執行TestClone,打印出:

C:\clone>javac *.java   C:\clone>java TestClone   myClone2.name=clone1 myClone2.boolValue=true myClone2.intValue=100   myClone2.listValue.size():3   myClone2.element.equals(myClone1.element):true   myClone2.element.name:element1   myClone1.listValue.size():4   myClone1.element.name:Element2   myClone2 equals myClone1: false   C:\clone>

我們發現,對于對象里的List,Element等復合屬性,super.clone()只是簡單地賦值,沒有采取克隆手段。也就是說,修改被克 隆后的對象值,會影響到原對象。

怎么進行深層次的克隆呢?

答案是,我們只能手動在重載的clone()方法里,對屬性也分別采用克隆操作。當然條件是,屬性類也得支持克隆操作

class MyClone implements Cloneable {        ...       public Object clone() {           try {                MyClone myClone = (MyClone)super.clone();               //分別對屬性加以克隆操作                myClone.element = this.element.clone();                              myClone.listValue = new ArrayList();               for (Element ele:this.listValue) {                    myClone.listValue.add(ele.clone());                }                                         return myClone;            } catch (CloneNotSupportedException e) {               return null;            }        }        ...   }    //讓Element類也支持克隆操作   class Element implements Cloneable   {        ...       public Element clone() {           try {               return (Element)super.clone();            } catch (CloneNotSupportedException e) {               return null;            }        }   }

深層次的克隆操作往往存在效率問題,尤其是需要讓List,Map等集合類也支持深層次的克隆操作時。

結合范例,比較深入地介紹了Java語言的克隆屬性,以及克隆的實現方法等。同時分析了深層次克隆的概念,實現,以及存在的問題等。

關于如何解析Java語言的對象克隆特性就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

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

AI

伊吾县| 揭阳市| 体育| 上林县| 麻城市| 桐柏县| 蒙城县| 普宁市| 鄂州市| 牡丹江市| 甘德县| 上杭县| 水富县| 利辛县| 苍溪县| 道真| 自治县| 常山县| 汉川市| 神木县| 保定市| 逊克县| 邵武市| 云林县| 英吉沙县| 宜兴市| 长治县| 兴安盟| 多伦县| 留坝县| 白玉县| 普格县| 邹城市| 浦城县| 广河县| 莱西市| 安新县| 黄冈市| 徐水县| 兖州市| 聂拉木县|