转载请注明出处,谢谢!

方法1:

   /*jdk >= 1.5*/
@SuppressWarnings("unchecked")
public static <T> T deepClone(T obj) {
T clonedObj = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
ois = new ObjectInputStream(bais);
clonedObj = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
} }
return clonedObj;
}

方法2:

    /*jdk >= 1.7*/
@SuppressWarnings("unchecked")
public static <T> T deepCopy(T srcObj) {
T targetObj = null;
try
(
ByteArrayInputStream bais = new ByteArrayInputStream(deepCopyRepo(srcObj, new ByteArrayOutputStream()).toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais)
)
{
targetObj = (T) ois.readObject();
}
catch (Exception e)
{
e.printStackTrace();
}
return targetObj;
}
public static ByteArrayOutputStream deepCopyRepo(Object obj,ByteArrayOutputStream baos) throws Exception {
try
(
ObjectOutputStream oos = new ObjectOutputStream(baos)
)
{
oos.writeObject(obj);
}
return baos;
}

注意事项:

1.若Java 7 build 105 版本及以上,推荐使用方法2;try-with-resources语句,ARM(Automatic Resource Management) 自动资源管理

2.被拷贝对象必须为可序列化的;当然,常用的如HashMap,ArrayList都是实现序列化的,直接使用本方法即可。

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

示例POJO:

 import java.io.Serializable;
import java.util.List; public class Person implements Serializable{
/*自定义版本*/
private static final long serialVersionUID = 1L; private String name;
private List<Person> children;
/*age属性因transient修饰,所以被序列化机制隔离*/
private transient int age;
public Person(String name,List<Person> children,int age){
this.name = name;
this.children = children;
this.age = age;
}
public Person(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Person> getChildren() {
return children;
}
public void setChildren(List<Person> children) {
this.children = children;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override/*根据jvm返回的hashCode判断对象相同*/
public String toString() {
return "Person"+ "@" + Integer.toHexString(this.hashCode())+" [name=" + name + ", children=" + children + ", age="
+ age + "]";
}
}

junit:

   @Test
public void testDeepCopy(){
List<Person> children = new ArrayList<>();
Person daughter = new Person("daughter",null,3);
Person son = new Person("son",null,1);
children.add(son);children.add(daughter);
Person father = new Person("sqiang",children,29);
System.out.println(father);
Person cfather = Utils.deepCopy(father);
System.out.println(cfather);
}

Console:

如图所示:

1.两组对象均不相同,实现了深拷贝

2.第二组的age=0,transient关键字对序列化起了作用。

Map,List,POJO深拷贝(序列化实现)方法与注意事项的更多相关文章

  1. java 复制Map对象(深拷贝与浅拷贝)

      java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...

  2. No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法

    org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.poj ...

  3. WPF控件深拷贝:序列化/反序列化

    原文:WPF控件深拷贝:序列化/反序列化 今天DebugLZQ在做WPF拖动总结的时候,遇到了这个问题.baidu了下,貌似没有解决这个问题的权威答案,遂写下这篇博文. 我想做的事情是:拖动一个窗体内 ...

  4. MessagePack Java Jackson Dataformat - POJO 的序列化和反序列化

    在本测试代码中,我们定义了一个 POJO 类,名字为 MessageData,你可以访问下面的链接找到有关这个类的定义. https://github.com/cwiki-us-demo/serial ...

  5. js引用类型深拷贝、浅拷贝方法封装

    引用类型的深拷贝.浅拷贝在前端领域一直是个很重要的知识点,不仅在业务中频繁使用,也是面试官们喜欢考的的知识点之一.本篇将封装引用类型的深拷贝.浅拷贝方法,并解决在封装过程中出现的问题. 一.浅拷贝 浅 ...

  6. 批量产生ssh2项目中hibernate带注解的pojo类的快捷方法

    近几个月一直在忙于项目组的ios应用项目的开发,没有太多时间去研究web应用方面的问题了.刚好,昨天有网友问到如何批量产生hibernate带注解的pojo类的快捷方法,所谓批量就是指将当前数据库中所 ...

  7. Map集合中value()方法与keySet()、entrySet()区别

    http://blog.csdn.net/liu826710/article/details/9001254 在Map集合中 values():方法是获取集合中的所有的值----没有键,没有对应关系, ...

  8. js实现深拷贝的一些方法

    在ECMAScript变量中包含两种不同类型的值:基本类型值和引用类型值. 基本类型值:Undefined.Null.Boolean.Number.String 引用类型值:Object.Array. ...

  9. java里面获取map的key和value的方法

    获取map的key和value的方法分为两种形式: map.keySet():先获取map的key,然后根据key获取对应的value: map..entrySet():同时查询map的key和val ...

随机推荐

  1. C# 命名空间和程序集

    一.命名空间 1.通过使用using关键字引入命名空间,减少代码量 命名空间对相关的类型进行逻辑分组,通过命名空间能快速的定位到相关的类型,例如:在System.IO命名空间下,定义了所有I/O操作的 ...

  2. Django学习日记01_环境搭建

    1. 使用Vagrant 创建ubuntu虚拟机: 首先安装vagrant,网上有比较多的方法,如:http://www.th7.cn/system/mac/201405/55421.shtml 我使 ...

  3. NPOI 1.2 教程

    NPOI 1.2 教程官方地址 很多人可能对NPOI还很陌生,别担心,通过本教程你将对NPOI有进一步的认识和理解. 目录 1. 认识NPOI 2. 使用NPOI生成xls文件 2.1 创建基本内容 ...

  4. ngx-bootstrap使用02 Accordion组件的使用

    1 Accordion组件 该组件通过一个可折叠的控制面板去在有限空间内显示更多的信息 according组件在可折叠指令的最外层,该组件提供了一些列的项目列表去显示被折叠的内容,这些项目列表包含he ...

  5. 《UNIX环境高级编程》第七章进程环境

    7.2 main函数 1.C程序总是从main函数开始执行的,原型:int main(int argc,char *argv[]);argc是命令行参数的个数argc是指向参数的各个指针所构成的数组2 ...

  6. 【Java框架型项目从入门到装逼】第七节 - 学生管理系统项目搭建

    本次的教程是打算用Spring,SpringMVC以及传统的jdbc技术来制作一个简单的增删改查项目,对用户信息进行增删改查,就这么简单. 1.新建项目 首先,打开eclipse,新建一个web项目. ...

  7. SQL Server 禁用扩展存储过程

    概述 扩展存储过程是 SQL Server 实例可以动态加载和运行的 DLL.扩展存储过程是使用 SQL Server 扩展存储过程 API 编写的,可直接在 SQL Server 实例的地址空间中运 ...

  8. dlib人脸关键点检测的模型分析与压缩

    本文系原创,转载请注明出处~ 小喵的博客:https://www.miaoerduo.com 博客原文(排版更精美):https://www.miaoerduo.com/c/dlib人脸关键点检测的模 ...

  9. python学习笔记(四)-数据类型

    0. 在 Python 中的数据类型详解 http://www.cnblogs.com/scios/p/8026576.html 1. 为什么布尔类型(bool)的 True 和 False 分别用 ...

  10. JS实现EasyUI ,Datagrid,合并单元格功能

    为了实现datagrid的合并单元格效果,datagrid的数据加载方式肯定是要写在JS文件内部的. 一:在JS内部添加Datagrid数据加载方法如下: $("#id").dat ...