java 深度拷貝 復制 深度復制


1、深度拷貝、復制代碼實現

最近需要用到比較兩個對象屬性的變化,其中一個是oldObj,另外一個是newObj,oldObj是newObj的前一個狀態,所以需要在newObj的某個狀態時,復制一個一樣的對象,由於JAVA不支持深層拷貝,因此專門寫了一個方法。

 

方法實現很簡單,提供兩種方式:

一種是序列化成數據流,前提是所有對象(對象中包含的對象...)都需要繼承Serializable接口,如果都繼承了那很容易,如果沒有繼承,而且也不打算修改所有類,可以用第二種方式。

第二種是將對象序列化為json,通過json來實現拷貝,這種方式需要用到net.sf.json.JSONObject。

 

具體代碼如下:

import net.sf.json.JSONObject;

import java.io.*;

class deepCopy {
    /**
     * 深層拷貝
     *
     * @param <T>
     * @param obj
     * @return
     * @throws Exception
     */
    static <T> T copy(T obj) throws Exception {
        //是否實現了序列化接口,即使該類實現了,他擁有的對象未必也有...
        if(Serializable.class.isAssignableFrom(obj.getClass())){
            //如果子類沒有繼承該接口,這一步會報錯
            try {
                return copyImplSerializable(obj);
            } catch (Exception e) {
                //這里不處理,會運行到下面的嘗試json
            }
        }
        //如果序列化失敗,嘗試json序列化方式
        if(hasJson()){
            try {
                return copyByJson(obj);
            } catch (Exception e) {
                //這里不處理,下面返回null
            }
        }
        return null;
    }

    /**
     * 深層拷貝 - 需要類繼承序列化接口
     * @param <T>
     * @param obj
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    private static <T> T copyImplSerializable(T obj) throws Exception {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;

        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;

        Object o = null;
        //如果子類沒有繼承該接口,這一步會報錯
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            bais = new ByteArrayInputStream(baos.toByteArray());
            ois = new ObjectInputStream(bais);

            o = ois.readObject();
            return (T) o;
        } catch (Exception e) {
            throw new Exception("對象中包含沒有繼承序列化的對象");
        } finally{
            try {
                assert baos != null;
                baos.close();
                assert oos != null;
                oos.close();
                assert bais != null;
                bais.close();
                assert ois != null;
                ois.close();
            } catch (Exception e2) {
                //這里報錯不需要處理
            }
        }
    }

    /**
     * 是否可以使用json
     * @return
     */
    private static boolean hasJson(){
        try {
            Class.forName("net.sf.json.JSONObject");
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 深層拷貝 - 需要net.sf.json.JSONObject
     * @param <T>
     * @param obj
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    private static <T> T copyByJson(T obj) throws Exception {
        return (T) JSONObject.toBean(JSONObject.fromObject(obj),obj.getClass());
    }
}

  

 

只需要調用copy方法就行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM