JAVA 深层拷贝 DeepCopy的使用详解

高洛峰
高洛峰 原创
2017-01-19 11:29:36 1540浏览

方法实现很简单,提供两种方式:
一种是序列化成数据流,前提是所有对象(对象中包含的对象...)都需要继承Serializable接口,如果都继承了那很容易,如果没有继承,而且也不打算修改所有类,可以用第二种方式。

第二种是将对象序列化为json,通过json来实现拷贝,这种方式需要用到net.sf.json.JSONObject。
具体代码如下:

    public class DeepCopy {  
        /** 
         * 深层拷贝 
         *  
         * @param <T> 
         * @param obj 
         * @return 
         * @throws Exception 
         */  
        public 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")  
        public 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 {  
                    baos.close();  
                    oos.close();  
                    bais.close();  
                    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")  
        public static <T> T copyByJson(T obj) throws Exception {  
            return (T)JSONObject.toBean(JSONObject.fromObject(obj),obj.getClass());  
        }  
    }

只需要调用copy方法就行。

更多JAVA 深层拷贝 DeepCopy的使用详解相关文章请关注PHP中文网!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。