Java 对象深拷贝

需求

写一个java对象深拷贝工具,用以对象深拷贝。

分析

在 Java 中,变量间值的传递分为两种。对于 int,char,string,等基本数据类型进行值传递时,使用值传递。即原变量 a 的值与新变量 b 的值相等,且 a 与 b 拥有不同的内存地址;对于非基本数据类型的变量进行传值时使用引用传值。即原变量 a 与新变量 b 的值相同(因为他们都指向相同的内存地址),且 a 与 b 拥有相同的内存地址。

基本数据类型传值示意

int a = 10;
int b = a;

如下图,当执行 int a = 10; 时,JVM 会先对变量 a 分配内存 0x0001 , 并在其中存储数据 10。当执行 int b = a; 时,JVM 也会为变量 b 分配一块内存 0x0011 ,并在其中存储 10。
在这里插入图片描述

引用数据类型传值示意

User a = new User();
User b = a;

// 或 方法传值

User a = new User();
addUser(a);
private void addUser(User b){
// …… 业务省略
}

如下图,当执行 User a = new User(); 时,JVM 会分配一块内存,其中存储着对象 User 的初始化信息,紧接着,JVM 将该内存的地址 0x0001 分配给变量 a;当程序执行到 User b = a;addUser(a); 时,
在这里插入图片描述

浅拷贝

对基本数据类型进行值传递,对引用数据类型进行引用传递的拷贝,为浅拷贝。

深拷贝

对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,为深拷贝。

综上,浅拷贝与深拷贝的差异在于对引用对象的拷贝,如果是的引用类型的数据拷贝与基本数据类型的拷贝达到相同的效果(除了值相同外,其他所有都不相同)则认为完成了数据深拷贝。

实现

  • 序列化拷贝

先将对象序列化,然后再反序列化为一个新的对象。最简单的序列化拷贝方法是结合JSON,先将对象转为JSON,再将JSON转为一个新的对象。

使用 googleGSON 序列化和反序列化代码如下:

// 对象 a
User a = new User();
// 创建 Gson 实例
Gson gson = new Gson();
// 序列化为 json 字符串
String jsonStr = gson.toJson(a);
// 反序列化 json 字符串为 对象 b 
User b = gson.fromJson(jsonStr,User.class);

// ================ Gson 对集合数据的处理,如 List<User>  ================
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
String usersStr = gson.toJson(users);
// 使用 TypeToken 对集合等非单一包装对象处理
List<TagEntry> usersCopy= gson.fromJson(usersStr ,  new TypeToken<List<User>>(){}.getType());

另一种常用序列化拷贝是借助于 commons-lang 工具包下的 org.apache.commons.lang.SerializationUtils 类,代码如下

// User 必须实现 Serializable
User a = new User();
User b = (User)SerializationUtils.clone(a);

注: 采用 SerializationUtils 工具序列化拷贝的对象必须实现 Serializable 接口。

总结

以上介绍了浅拷贝和深拷贝的概念,并且介绍了两种常用的深拷贝方法。当然,也可以自己实现深拷贝,比如通过反射实现,或者通过重写 clone 方法实现等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值