官术网_书友最值得收藏!

4.4 對象復制

前一章已經討論過值類型和引用類型,當使用賦值運算符(=)或通過方法的參數傳遞時,它們的默認處理方式是不同的。其中,值類型會創建數據的副本(深復制),引用類型會傳遞對象的引用地址(淺復制),String類型則由于其自身的特殊性而與其他引用類型的表現有所不同。

如果代碼中需要完全復制一個對象,即實現對象的深復制,可以使用兩種方法來實現,分別是讓對象的類型實現Cloneable接口或Serializable接口。首先看Cloneable接口的使用。

4.4.1 實現Cloneable接口

實現Cloneable接口的類只需要實現clone()方法,其返回值為Object類型。例如,下面的代碼(CTank.java文件)創建CTank類。

在clone()方法中,首先創建一個新的CTank實例,然后將當前實例的各個字段的數據賦值給新的實例,最后返回新的實例對象。

下面的代碼測試賦值運算符(=)和clone()方法復制對象的不同。

    public static void main(String[] args) {
        CTank t1 = new CTank();
        t1.model = "85";
        CTank t2 = t1;
        t2.model = "99";
        CTank t3 = (CTank)t1.clone();
        t3.model = "99A";
        //
        System.out.println(t1.model);
        System.out.println(t2.model);
        System.out.println(t3.model);
    }

圖4-2 實現Cloneable接口以復制對象

代碼執行結果如圖4-2所示。

示例中,t1對象通過new CTank()代碼創建,并設置model字段為85。然后,使用賦值運算符將其引用賦值給t2對象,此時,t2和t1引用了同一對象體(可以視為內存中某個區域)。接著,重新設置t2對象的model字段,而t1對象的數據同樣也會改變,前兩個輸出結果驗證了這一點。

對于t3對象,使用t1.clone()方法進行復制,這樣,t3和t1實際上是完全不同的兩個對象。修改t3對象的model字段時,并不會改變t1對象的數據,代碼的輸出結果驗證了這一點。

4.4.2 實現Serializable接口

Serializable接口定義在java.io包中,使用時需要導入。下面的代碼(CTank.java文件)修改CTank類的定義。

實現Serializable接口時并不需要實現什么成員,它只是告訴編譯器,此類型的對象是可序列化(也稱為可串行化)的。

實際應用中,序列化操作包括兩個方向,即對象的輸出與輸入。接下來會使用java.io包中的一系列輸入(input)和輸出(output)類型來完成序列化和反序列化操作。

下面的代碼使用序列化來復制CTank對象。

圖4-3 使用序列化復制對象

代碼輸出結果如圖4-3所示。

序列化操作(輸出)中,主要使用了ByteArray OutputStream類和ObjectOutputStream類。其中,使用ObjectOutputStream對象的writeObject()方法將t1對象寫入ByteArrayOut putStream對象,然后使用close()方法關閉ObjectOutputStream對象。

反序列化操作(輸入)中,使用ByteArrayInputStream類和ObjectInputStream類。其中,使用ObjectInputStream對象中的readObject()方法從ByteArrayOutputStream對象中讀取字節數組數據,強制轉換為CTank對象并賦值給t2對象。

代碼的最后,先輸出t1對象的model和weapon字段,然后。修改t2對象的weapon字段。通過觀察輸出信息可以看到,t2對象完成了對t1對象的完全復制,修改t2對象的weapon字段時并不會影響t1對象。

關于序列化,需要說明的一點是,如果類型的字段不需要或不允許序列化時,可以使用transient關鍵字定義。例如,引用外部資源的對象,只能在恢復對象以后重新打開,無法通過序列化來保持資源的連接狀態。

主站蜘蛛池模板: 安康市| 涿鹿县| 天峨县| 南平市| 和田市| 临城县| 乡城县| 渭南市| 乃东县| 瑞昌市| 吉林市| 望江县| 天长市| 宽甸| 志丹县| 临湘市| 繁昌县| 鄂托克前旗| 罗城| 长垣县| 天水市| 华宁县| 龙岩市| 富裕县| 潼南县| 太谷县| 安顺市| 慈利县| 沧源| 阿拉善左旗| 庆元县| 甘肃省| 金乡县| 西宁市| 海阳市| 房产| 台北市| 上虞市| 洞口县| 新宾| 莆田市|