您的位置:首页 > 房产 > 家装 > 什么叫一级域名二级域名_网站流量怎么查看_青岛网络优化代理_成都网站建设

什么叫一级域名二级域名_网站流量怎么查看_青岛网络优化代理_成都网站建设

2024/12/23 16:16:16 来源:https://blog.csdn.net/q251932440/article/details/142438393  浏览:    关键词:什么叫一级域名二级域名_网站流量怎么查看_青岛网络优化代理_成都网站建设
什么叫一级域名二级域名_网站流量怎么查看_青岛网络优化代理_成都网站建设

🌐Gson的jar包提供到本文上方,欢迎自取🌐


前言

🌐在 Java 编程中,克隆对象是一项常见的需求,特别是在处理不可变对象、避免引用传递时,深度克隆显得尤为重要。虽然 Java 提供了 clone() 方法,但由于它的限制(如 Cloneable 接口的复杂性),实际项目中并不常用。为此,许多开发者选择使用第三方工具来实现深度克隆,其中,Gson 是一个非常流行且简洁的解决方案。

本文将介绍什么是深度克隆与浅克隆、clone()方法调用的细节问题和如何通过 Gson 实现对象的深度克隆,并分析其优缺点。


什么是深度克隆?浅克隆?

对象克隆指的是把A对象的属性值完全拷贝给B对象,也叫对象拷贝/对象复制

但是object默认的是浅克隆

不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来

基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。

🔴注意:浅克隆会导致引用数据类型的地址多个对象共用的情况,如果一个对象对其地址所记录的值进行了修改,另外一个对象里面的的值也会跟着一起变动,因为两个对象的地址值相同,指向相同的具体数值。

🌐clone()的问题与方法实现——以User类为例

❓问题:

在User类中重写clone()方法,不能直接在main下创建对象直接调用,至于为什么不能这样调用在寻找资料和ai后都得不到很好地理解,把原因归结与protected修饰符不能直接通过某个对象实例在外部类调用,如下图:

直接调用会出现'clone()' has protected access in 'java.lang.Object'报错

但是我换了别的方法试了一下别的方法来测试得到不一样的结果

我先在Animal类中定义了一个protected修饰的eat方法

然后在另外一个包创建一个Dog类,继承Animal,而且不对eat方法作重写

最后我们到测试类的main方法下创建一个Dog对象,并调用继承父类用protected修饰的eat()方法

最后运行发现,没有任何报错而且成功调用了继承父类用protected修饰的eat()方法

得到运行结果:


🔷思考与结论:

同样是父类其他包的子类,同样是父类用protected修饰的方法,为什么不能在main方法中被子类对象实例调用呢?

为了解决这个疑惑,我找到了clone()的源代码,发现有一个native关键字,可能是native的原因导致上述问题,如下图:

而且通过学习我们得知,想要实现JavaBean类调用clone()方法还需要实现一个Cloneable接口。

Cloneable 是一个标记接口(没有方法),它告诉 JVM 某个类是可以被克隆的

经过上述分析,个人没有找到protected的影响,但是找到了两个可能的原因就是:

  • 实现克隆调用需要实现Cloneable接口
  • 受到native关键字的影响

🔷实现:
  1. 在JavaBean类中重写Object中的clone方法
  2. 让JavaBean类实现Cloneable接口
  3. 创建对象并调用clone方法(clone返回的是Object对象,需要强制转换)

1.在JavaBean类中重写Object中的clone方法:

2.让JavaBean类实现Cloneable接口:

3.创建对象并调用clone方法(注意接收对象的时候要强转):

先点击向方法签名添加异常

这样,一个浅克隆就实现了

但是我们上面提及,浅克隆会导致引用数据类型的地址多个对象共用的情况,如果一个对象对其地址所记录的值进行了修改

代码示例:

 public static void main(String[] args) throws CloneNotSupportedException {//定义一个数组并赋值int[] arr = {1,2,3,4,5};//新建一个User对象User u1 = new User(001,"qiao","123456","kimi",arr);User u2 = new User();u2 = (User) u1.clone();System.out.println(u1);System.out.println(u2);int[] data = u1.getData();data[0] = 100;System.out.println(u1);//User{id=1, username='qiao', password='123456', path='kimi', data=[100, 2, 3, 4, 5]}System.out.println(u2);//User{id=1, username='qiao', password='123456', path='kimi', data=[100, 2, 3, 4, 5]}}
黑马程序员的这张图片可以帮助我们很好地理解浅克隆

而深度克隆指的是不仅复制对象本身,还复制该对象所有引用的对象,确保克隆对象与原对象之间没有共享的引用。与之相对的浅克隆,只会复制对象本身,而不会递归复制其引用的对象。

🌐通过clone()方法实现深克隆

我们需要修改一下JavaBean类中的clone()方法重写内容:

 @Overrideprotected Object clone() throws CloneNotSupportedException {int[] data = this.data;int[] newData = new int[data.length];for (int i = 0; i < data.length; i++) {newData[i] = data[i];}User u = (User)super.clone();u.data = newData;return u;}

但是这样操作有点麻烦,所以我们会使用一个第三方工具Gson 


Gson 简介

Gson 是 Google 提供的一个用于将 Java 对象与 JSON 互相转换的库。它具有以下特点:

  1. 支持简单和复杂的对象转换。

  2. 无需配置即可处理大部分对象。

  3. 能够处理泛型类。

  4. 性能高效、使用简单。

尽管 Gson 主要用于 JSON 序列化与反序列化,但它的这一特性可以巧妙地用于对象的深度克隆。通过将对象转换为 JSON 字符串,再从 JSON 字符串中反序列化回对象,我们可以实现深度克隆。


🌐使用 Gson 实现深度克隆

使用之前先在项目目录下创建lib包,将gson的jar包放在lib包下:

然后右键该jar包,点击黄色箭头处完成导入:

接下来实现对象的深度克隆非常简单,只需以下两步:

  1. 将对象序列化为 JSON 字符串(toJson)

  2. 从 JSON 字符串反序列化为一个新的对象(fromJson)

示例代码

import com.google.gson.Gson;public class Main {public static void main(String[] args) throws CloneNotSupportedException {int[] arr = {1,2,3,4,5};User u1 = new User(001,"zhangsan","123456","gril",arr);System.out.println(u1);//第三方深克隆工具Gson gson = new Gson();String json = gson.toJson(u1);User u2 = gson.fromJson(json, User.class);System.out.println(u1);//User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}System.out.println(u2);//User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}int[] data = u1.getData();data[0] = 100;System.out.println(u1);//User{id=1, username='zhangsan', password='123456', path='gril', data=[100, 2, 3, 4, 5]}System.out.println(u2);//User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}
}

运行结果

原对象:User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}
克隆对象:User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}
修改后的原对象:User{id=1, username='zhangsan', password='123456', path='gril', data=[100, 2, 3, 4, 5]}
克隆对象不受影响:User{id=1, username='zhangsan', password='123456', path='gril', data=[1, 2, 3, 4, 5]}

通过输出结果可以看出,原对象和克隆对象之间没有共享引用,修改克隆对象的地址不会影响原对象,说明我们成功实现了深度克隆。


Gson 深度克隆的优缺点

🌐优点

  1. 实现简单:使用 Gson 实现深度克隆的代码非常简洁,仅需两步即可完成。

  2. 适用于复杂对象:Gson 可以处理包含嵌套对象和集合的复杂 Java 对象。

  3. 无需额外实现接口:不同于 clone() 方法,使用 Gson 不需要让类实现 Cloneable 接口,也不需要自己处理克隆逻辑。

🌐缺点

  1. 性能开销:由于 Gson 需要将对象转换为 JSON 字符串,再从 JSON 字符串中解析出对象,这个过程相较于原生的克隆操作稍慢,特别是在处理大对象时性能损耗较为明显。

  2. 不适用于所有场景:Gson 无法处理带有瞬态字段(transient)或不希望被序列化的对象,这些字段会在克隆过程中丢失。

  3. 依赖 JSON 表示:对象的所有字段都必须能够被正确转换为 JSON 格式,对于某些复杂类型或带有循环引用的对象,Gson 可能无法处理。


总结

在 Java 中,深度克隆是一个常见需求,而 Gson 提供了一种简单高效的解决方案。虽然它的主要用途是序列化与反序列化,但它也能够通过这种方式轻松实现深度克隆。对于大部分场景,Gson 是一个非常不错的选择。不过,如果你的对象过于复杂或者对性能要求较高,可能需要考虑其他克隆工具。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com