克隆Java(克隆java项目后爆红)

createh52个月前 (02-01)技术教程11

一. 泛型克隆接口:

o JDK自带的Cloneable接口虽然表明一个类支持克隆,但并未提供实际的方法实现。

o 文档提出了一种泛型化的Cloneable接口变体,该接口要求实现类提供一个类型安全的clone()方法,例如Cat类通过实现Cloneable<Cat>接口并重写clone()方法,从而能够直接返回Cat类型克隆对象,避免了类型转换的麻烦。

二. 泛型克隆类CloneSupport:

o 由于手动实现clone()方法仍需处理如CloneNotSupportedException等异常以及调用父类Object的clone()方法,为此创建了一个名为CloneSupport的基类。

o Dog类通过继承CloneSupport<Dog>,无需自行编写clone()方法就能自动获得正确且类型安全的克隆功能,前提是不能再继承其他非CloneSupport类,这是由于Java单继承限制。

三. 深克隆与便捷方法:

o 实现标准Cloneable接口进行克隆时,默认只能得到浅克隆,即原始对象引用的其他对象只做引用复制而非内容复制。

o 若要实现深克隆,可以使用第三方库如Hutool提供的ObjectUtil.cloneByStream()方法,但这要求被克隆的对象必须实现Serializable接口。

o Hutool还提供了clone(obj)和cloneIfPossible(obj)等静态方法,方便开发者快速、安全地进行对象克隆操作,具体使用细节可查阅相关文档。

参考Hutool克隆的核心包

泛型的克隆接口和克隆类

我们知道,JDK中的Cloneable接口只是一个空接口,并没有定义成员,它存在的意义仅仅是指明一个类的实例化对象支持位复制(就是对象克隆),如果不实现这个类,调用对象的clone()方法就会抛出CloneNotSupportedException异常。而且,因为clone()方法在Object对象中,返回值也是Object对象,因此克隆后我们需要自己强转下类型。

泛型克隆接口

因此,Cloneable接口应运而生。此接口定义了一个返回泛型的成员方法,这样,实现此接口后会提示必须实现一个public的clone方法,调用父类clone方法即可:

/**
 * cat 类,使用实现Cloneable方式
 *
 */
private static class Cat implements Cloneable<Cat>{
  private String name = "miaomiao";
  private int age = 2;
  
  @Override
  public Cat clone() {
    try {
      return (Cat) super.clone();
    } catch (CloneNotSupportedException e) {
      throw new CloneRuntimeException(e);
    }
  }
}

泛型克隆类

但是实现此接口依旧有不方便之处,就是必须自己实现一个public类型的clone()方法,还要调用父类(Object)的clone方法并处理异常。于是CloneSupport类产生,这个类帮我们实现了上面的clone方法,因此只要继承此类,不用写任何代码即可使用clone()方法:

/**
 * dog 类,用于继承CloneSupport类
 *
 */
private static class Dog extends CloneSupport<Dog>{
  private String name = "wangwang";
  private int age = 3;
}

当然,使用CloneSupport的前提是你没有继承任何的类,谁让Java不支持多重继承呢(你依旧可以让父类继承这个类,如果可以的话)。如果没办法继承类,那实现cn.hutool.clone.Cloneable也是不错的主意,因此hutool提供了这两种方式,任选其一,在便捷和灵活上都提供了支持。

深克隆

我们知道实现Cloneable接口后克隆的对象是浅克隆,要想实现深克隆,请使用:

ObjectUtil.cloneByStream(obj)

前提是对象必须实现Serializable接口。

ObjectUtil同样提供一些静态方法:clone(obj)cloneIfPossible(obj) 用于简化克隆调用,详细的说明请查看核心类的相关文档。

相关文章

你还在用BeanUtils进行对象属性拷贝?

在做业务的时候,为了隔离变化,我们会将DAO查询出来的DO和对前端提供的DTO隔离开来。大概90%的时候,它们的结构都是类似的;但是我们很不喜欢写很多冗长的b.setF1(a.getF1())这样的代...

Java的深拷贝与浅拷贝详解(java的深拷贝与浅拷贝详解图)

前言拷贝,顾名思义,就是复制一个一模一样的东西。那么放到对象上,也就是复制一个一模一样的对象了。Java中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、用作方法参数或返...

java对象深拷贝的三种实现方式,可避免循环引用导致的堆栈溢出

在java编程中,难免要对一个对象进行复制,复制分为深拷贝和浅拷贝。浅拷贝只复制对象本身,对于对象引用的其他对象不进行复制。 深拷贝则将对象与引用对象,全部进行拷贝。最简单的深拷贝就是自己new一个对...

Java常用的几种属性拷贝工具类使用总结

Java属性拷贝工具类使用总结对项目中经常使用的属性拷贝工具类进行总结:org.apache.commons.beanutils.BeanUtilsorg.apache.commons.beanuti...

Java中深拷贝、浅拷贝、赋值的区别?如何自己写个深拷贝工具类?

#头条创作挑战赛#为什么要了解JavaBean深拷贝的机制目前大家都在常用已经封装好的工具类,很少去深入了解多种实现方式;此处提出一种简单的实现原理,也是巩固Java中关于反射的用法和知识;目的:可以...

java浅拷贝BeanUtils.copyProperties引发的RPC异常

背景近期参与了一个攻坚项目,前期因为其他流程原因,测试时间已经耽搁了好几天了,本以为已经解决了卡点,后续流程应该顺顺利利的,没想到 人在地铁上,bug从咚咚来~没有任何修改的服务接口,抛出异常:jav...