Java对象的Clone

本文介绍了Java中对象克隆的重要性,详细讲解了浅克隆和深克隆的概念及实现方式。通过实现Cloneable接口并重写clone()方法,可以进行浅克隆。对于包含复杂引用的对象,深克隆可以通过序列化和反序列化实现。深克隆不仅复制对象本身,还复制其引用的其他对象,确保独立性。
摘要由CSDN通过智能技术生成

1.对象Clone的意义

Java中对象的克隆是通过实现Cloneable接口,重写Object的clone()来实现的。Object类clone()源代码如下所示:

  • Object中的clone方法是protected的,所以要使用clone就必须继承Object类(默认)。并且为了可以使其它类调用该方法,覆写克隆方法时必须将其作用域设置为public;
  • Object中的clone方法是native修饰的方法,因此它的实现是取决于本地代码。native方法的效率一般来说都是远高于java中的非native方法;
  • 通常克隆对象都是通过调用super.clone()方法来获取克隆对象的,所以任何克隆的过程最终都将到达java.lang.Object的clon-e()方法。但是在覆写clone()方法时,这个类需要继承Clonable接口,这个接口中没有定义方法,他类似于Random-Access这些接口类,只做为一种标识存在。如果clone类没有实现Cloneable接口,并调用了Object的clone() 方法(也就是调用了super.-Clone() 方法),那么Object 的 clone() 方法就会抛出 CloneNotSupportedException 异常;
  • 在克隆java对象的时候不会调用构造器,对任何的对象x,都有x.clone() !=x,克隆对象与原对象一定不是同一个对象;
  • 对任何的对象x,都有x.clone().getClass()==x.getClass(),克隆对象与原对象的类型一样;
  • 如果对象x的equals()方法定义恰当(不包含x.hashCode()方法的调用),那么x.clone().equals(x)应该成立。
protected native Object clone() throws CloneNotSupportedException;

       为什么需要克隆对象?直接new一个对象不行吗?答案是:克隆的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。那么我把这个对象的临时属性一个一个的赋值给我新new的对象不也行嘛?答案是可以的,但是这种方式一来麻烦(如果这个对象属性很多,而且有很多相互关联引用的对象和集合,复杂度将远超乎你想像);二来,大家通过上面的源码都发现了clone是一个native的底层实现方法。我们常见的Object a=new Object();Object b;b=a;这种形式的代码复制的是引用,即对象在内存中的地址,a和b对象仍然指向了同一个对象。而通过clone方法赋值的对象跟原来的对象时同时独立存在的。Clone一般分为深克隆和浅克隆。

2.浅克隆

       浅克隆(拷贝):复制一个对象的实例,但是这个对象中包含的其它的对象还是共用的。一般用super.clone()方法,clone的对象就是浅克隆。浅克隆

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中的`clone()`方法用于创建并返回一个对象的拷贝,这个拷贝具有与原始对象相同的状态和属性。要使用`clone()`方法,需要确保被克隆对象实现了`Cloneable`接口。 下面是使用`clone()`方法进行对象克隆的示例代码: ```java class Person implements Cloneable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // 重写clone()方法 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public String getName() { return name; } public int getAge() { return age; } } public class Main { public static void main(String[] args) { Person person1 = new Person("Alice", 25); try { // 克隆person1对象 Person person2 = (Person) person1.clone(); System.out.println("person1: " + person1.getName() + ", " + person1.getAge()); System.out.println("person2: " + person2.getName() + ", " + person2.getAge()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } ``` 输出结果为: ``` person1: Alice, 25 person2: Alice, 25 ``` 在上述示例中,`Person`实现了`Cloneable`接口并重写了`clone()`方法。在`main`方法中,通过调用`person1.clone()`创建了一个新的对象`person2`,并且`person1`和`person2`的属性值相同。 需要注意的是,`clone()`方法是拷贝,即只会复制对象的字段值,而不会复制对象引用的其他对象。如果需要进行拷贝,需要自行实现相关逻辑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抽离的心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值