推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

Java如何对一个对象进行深拷贝?

   2023-07-03 网络整理佚名1820
核心提示:clone()其实是浅拷贝,所以在重写User类的clone()方法时,对象需要调用.Java提供了序列化的能力,我们可以先将源对象进行序列化,再反序列化生成拷贝对象。但是,使用序列化的前提是拷贝的类(包括其成员变量)需要实现接口。Gson可以将对象序列化成JSON,也可以将JSON反序列化成对象,所以我们可以用它进行深拷贝。

作者:吴大山
来源:http://wudashan.com/2018/10/14/Java-Deep-Copy/

介绍

在Java语言中,当我们需要复制一个对象时,有两种类型的复制:浅复制和深复制。 浅拷贝只复制源对象的地址,因此当源对象的值发生变化时,复制对象的值也会发生变化。 深拷贝复制源对象的所有值,因此即使源对象的值发生变化,复制的对象的值也不会改变。 如下图所示:

了解了浅拷贝和深拷贝的区别后,本博客将教你几种深拷贝的方法。

复制对象

首先,让我们定义需要复制的简单对象。

如上面的代码,我们定义了一个User类,其中包含姓名和地址,这不是一个字符串,而是另一个类,其中包含国家和城市。 这里省略了构造函数和成员变量的get()和set()方法。 接下来我们将详细介绍如何深拷贝User对象。

方法构造器

我们可以通过调用构造函数来进行深拷贝。 如果形参是基本类型和字符串,则直接赋值,如果是对象,则新建。

测试用例

方法2重载clone()方法

父类有一个clone()复制方法,但它是一个类型,我们需要重写它,将其修改为类型。 另外,子类还需要实现接口来告诉JVM这个类可以被复制。

重写代码

我们来修改User类、类和实现接口来支持深拷贝。

需要注意的是,super.clone()实际上是浅拷贝,所以重写User类的clone()方法时,对象需要调用.clone()重新赋值。

测试用例

方法3 Lang序列

Java提供了序列化的能力。 我们可以先序列化源对象,然后反序列化生成复制对象。 但是,使用序列化的前提是复制的类(包括其成员变量)需要实现接口。 Lang包封装了Java序列化,我们可以直接使用。

重写代码

我们来修改User类、类、实现接口来支持序列化。

测试用例

方法四 Gson序列化

Gson可以将对象序列化为JSON,也可以将JSON反序列化为对象,因此我们可以用它来进行深拷贝。

测试用例

方法五序列化

与Gson类似,对象可以序列化为JSON。 明显的区别是复制的类(包括其成员变量)需要有一个默认的无参数构造函数。

重写代码

让我们修改 User 类,并实现默认的无参构造函数来支持它。

测试用例

总结

说了这么多深拷贝的实现方法,到底哪种方法最好呢? 最简单的判断就是根据被复制的类(包括其成员变量)是否提供深拷贝构造函数、是否实现接口、是否实现接口、是否实现默认的无参构造函数来进行选择。 详细考虑见下表:

参考阅读

深拷贝实现代码:

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON