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方法就行。
自动化学习。