Java的克隆

说到克隆,本质都是使用一个已经实例化完成的对象的副本。 对于基本类型比较简单。比方说我们想复制一个变量,

int index = 12345;

很简单,

int indexCopy = index;

如果我们想复制一个对象呢,情况就变的有点复杂

Student student1 = new Student();
student1.setName("Michael");

Student student2 = student1;

啧啧,作为新手,通常会会觉得这样的就完成了复制。 但实际情况是,当我们对 student1的 name进行更改时,student2的值就会被一起改变。

上面这个其实只是引用复制,大家都指向堆里的同一个引用,自然当数据发生变化时也会一起改变。 那么如何正确复制对象呢,这里就得说一下Java的Clone。

克隆

Java的克隆允许复制一个一模一样内容的对象出来,当改变A内容时,被克隆的B的内容不会一起改变。 为什么要克隆呢?其实很简单,当我们复制了一个对象的引用,新对象的数据在发生变更时会同时修改原对象的数据。而这并不是我们想要的,我们只想修改新对象的数据。克隆可以解决这种场景。 这里面有两种克隆,浅克隆和深克隆。

浅克隆- shallow clone

不管是浅克隆还是深克隆,都要先实现 Clonable接口,然后复写 clone()方法并改为 public。 举例有个 Student类

public class Student implements Clonebale{
    String name;

    @Override
    public Object clone() {
      Student stu = null;
      try{
          stu = (Student)super.clone();
      }catch(CloneNotSupportedException e) {
          e.printStackTrace();
      }
      return stu;
    }
}

然后我们从student1复制一个对象student2出来,

student1.setName("Michael");
Student student2 = student1.clone();
student2.setName("Rachel");

这时候我们再打印两个对象的值,就会发现这是两个完全不同的对象,分别叫 Michael和 Rachel了。

深克隆 - deep clone

当情况变的更复杂一点,比如在Student里引入一个对象 Subject

class Subject {
  String title;
}

class Student implement Cloneable{
    String name;
    Subject subject;
}

这时候我们再用student1克隆出student2的结果就会变成, name字段是一样的,然而subject字段却保持和student1一样。

如果我们想把克隆对象里的非基本类型也一并克隆的话,那么需要把引用的类型也同样实现克隆接口。 也就是说,subject类也需要实现 Cloneable

class Subject implements Clonable{
  String title;

  @Override
  public Object clone() {
    ....
  }
}

这样便成为深克隆了。

最后一种克隆方法

如果我们想克隆的对象有多个层次的类型引用,这时候把每一个类型都实现 Clonable接口是不现实的。 那么可以用序列化和发序列化的方法来实现克隆。

原文发布于微信公众号 - Android每日一讲(gh_f053f29083b9)

原文发表时间:2018-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猿人谷

浅谈C/C++中的指针和数组(一)

                                                       浅谈C/C++中的指针和数组(一)       指...

2175
来自专栏抠抠空间

面对对象总结

一、类 1、类的定义 1 class 类名: 2 类属性 3 类方法 如: 1 class Person: 2 kind = '人类' ...

3339
来自专栏Golang语言社区

Golang语言--细节汇总

slice和数组在声明时的区别:声明数组时,方括号内写明了数组的长度或使用...自动 计算长度,而声明slice时,方括号内没有任何字符。 对于slice有几个...

3699
来自专栏java达人

最有价值的50道java面试题(一)

来自骆昊的技术专栏 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,...

30210
来自专栏深度学习自然语言处理

谈一谈python中的魔法变量*args和**kwargs

,没有注释,没有封装,没有可读性。哎,幸亏发现及时,现在正在写一个新的任务,刚好可以好好弄弄架构和代码了!

983
来自专栏阿凯的Excel

Python读书笔记25(类的继承)

谈类的使用,怎能缺失类的继承!类的继承可以大大简化代码编辑工作。 为啥这么说呢! 因为一个类继承另外一个类的时候,可以自动获得另一个类的所有属性和方法! 原有的...

3486
来自专栏阿凯的Excel

Python读书笔记(变量)

前言:本系列为小编的读书笔记,非教学课程;小编只是想用平实的语言翻译一下自己所学的东西。 首先什么是变量呢? 百度百科:变量来源于数学,是计算机语言中能储存计算...

36910
来自专栏Java帮帮-微信公众号-技术文章全总结

【Java案例】九九乘法表

案例描述 输出九九乘法口诀表,如图1.4所示。 ? 图1.4 九九乘法口诀表 案例分析 观察九九乘法口诀表,可以得出图表的规律:总共有9行,第几行就有几个表达...

3869
来自专栏云霄雨霁

排序----快速排序

1200
来自专栏菜鸟计划

angularjs filter详解

过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果。 主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的...

3728

扫码关注云+社区

领取腾讯云代金券