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方法就行。

java 深度拷贝 复制 深度复制的更多相关文章

  1. Jquery的深度拷贝和深度克隆

    有人问,拷贝和克隆不都是“复制”的意思吗. 这位看官问的好,一般情况下是一样的,但在jquery中却有些不同.jqurey深度拷贝一般只js对象的复制,是$.extend()方法,jquery深度克隆 ...

  2. C++ 默认拷贝构造函数 深度拷贝和浅拷贝

    C++类默认拷贝构造函数的弊端 C++类的中有两个特殊的构造函数,(1)无参构造函数,(2)拷贝构造函数.它们的特殊之处在于: (1) 当类中没有定义任何构造函数时,编译器会默认提供一个无参构造函数且 ...

  3. 转载---Java集合对象的深度复制与普通复制

    原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...

  4. C++ 进阶5 拷贝构造 深度复制 运算符重载

    C++ 进阶5 拷贝构造 深度复制 运算符重载 20131026 例子: 运行环境是G++ 编译, /* * main.cpp * *  Created on: 2013年10月26日 *      ...

  5. [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2

    接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...

  6. 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet

    原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...

  7. 浅谈BeanUtils的拷贝,深度克隆

    1.BeanUtil本地简单测试在项目中由于需要对某些对象进行深度拷贝然后进行持久化操作,想到了apache和spring都提供了BeanUtils的深度拷贝工具包,自己写了几个Demo做测试,定义了 ...

  8. java 及 Jquery中的深复制 浅复制

    发现问题:最近 遇到由于复制对象之后,改变复制后的新变量,原先被复制的对象居然会跟着变. EX:java中: //holidayConfig.getEnd_time()会随着sTime的改变而改变 s ...

  9. C#深度拷贝和浅度拷贝方法

    C#浅度拷贝多用于值类型的复制,即 int a=1;int b=a; 设置b=2后不会影响a的值. 但如果对于引用类型class a=new class(); class b=a; 设置b.name= ...

随机推荐

  1. iOS开发CAAnimation类动画, CATransition动画

    #pragma mark - CAAnimation类.实现动画 #pragma mark ** CABasicAnimation 动画 - (IBAction)handleCABasicAnimat ...

  2. vagrant简单学习使用

    1.安装vagrant 旧版本的vagrant可以在http://downloads.vagrantup.com/下载,支持的系统平台有mac,debian/ubuntu, centos,window ...

  3. 发生dev_queue_xmit的时候,全部都是从ip_finish_output中来的吗

    也就是说啊,内核中的收发包的路径,很可能是经理driver_recv --> tcp -->driver_send这样一个过程,是个很长的路径呢...... 从dev_queue_xmit ...

  4. 请问:在delphi中怎样判断DBgrid中数据是否被修改,以便在退出窗口时加以提示

    若DBGrid.DataSource.DateSet为ADOQuery1,这样试一下:if ADOQuery1.Modified then ... procedure TForm1.FormClose ...

  5. 【Json】Newtonsoft.Json高级用法

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  6. 文件传输底层是二进制 所以在传输前可以通过 InputStreamer 指定传输出的编码格式

    文件传输底层是二进制 所以在传输前可以通过 InputStreamer 指定传输出的编码格式

  7. [洛谷P4717]【模板】快速沃尔什变换

    题目大意:给定多项式$A$和$B$,求$C$满足: $$C_n=\sum\limits_{x\oplus y=n}A_xB_y$$ 其中$\oplus$为位运算($or,and,xor​$) 题解:$ ...

  8. [洛谷P4847]银河英雄传说V2

    题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种: 1. $M\;x\;y:$把$x$所在的序列放在$y$所 ...

  9. [洛谷P3181][HAOI2016]找相同字符

    题目大意:给你两个字符串,求从两个字符串中各选择一个字串使得这两个字串相同的方案数. 题解:建广义$SAM$,对每个点求出在第一个串中出现次数和第二个串中出现次数,乘起来就行了 卡点:无 C++ Co ...

  10. 【BZOJ5329】【SDOI2018】战略游戏(圆方树,虚树)

    [BZOJ5329][SDOI2018]战略游戏(圆方树,虚树) 题面 BZOJ 洛谷 Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战 ...