活动地址:CSDN21天学习挑战赛
博客主页: XIN-XIANG荣
系列专栏:【Java SE】
一句短话: 难在坚持,贵在坚持,成在坚持!

文章目录

  • 1. Cloneable接口的介绍
  • 2. 浅拷贝的介绍和实例
  • 3. 深拷贝的介绍和实例
  • 4. clone方法总结

1. Cloneable接口的介绍

Cloneable是标记型的接口(空接口),它们内部都没有方法和属性,实现 Cloneable来表示该对象能被克隆,能使用Object.clone()方法。如果没有实现 Cloneable的类对象调用clone()就会抛出CloneNotSupportedException异常。

可以理解为Cloneable接口发挥的是标记功能,自定义类型需要用户自己标记出哪些类是可以clone的,这个标记就是去实现Cloneable接口,实现了Cloneable接口后就表明该类创建的对象可以被克隆。

而要想使一个类具备拷贝实例的功能,除了要实现Cloneable接口,还必须重写Object类的clone()方法。

可以看到Object类的clone()方法是被protected修饰的,所以需要在重写的clone()方法中通过super关键字去调用Object类中的clone()方法

2. 浅拷贝的介绍和实例

在拷贝一个对象时,对 对象的基本数据类型的成员变量进行拷贝,但对引用类型的成员变量只进行引用的传递,并没有创建一个新的对象,当对引用类型的内容修改会影响被拷贝的对象。简而言之:浅拷贝仅仅复制所拷贝的对象,而不复制它所引用的对象。

观察下面的代码,将Money类的实例作为了Person类的字段,new一个Person类的对象person1,将这个person1对象拷贝到person2中,这里的拷贝就是浅拷贝了,只是将person1对象的money引用拷贝到了person2,person1和person2中的momey指向的是同一个对象。

class Money {public double m = 666;
}
class Person implements Cloneable{int id;public Money money = new Money();public Person(int id) {this.id = id;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic String toString() {return "Person{" +"id=" + id +", money=" + money.m +'}';}
}
public class TestDemo3 {public static void main(String[] args) throws CloneNotSupportedException {Person person1 = new Person(1);Person person2 = (Person) person1.clone();System.out.println("通过person2修改前的结果");System.out.println(person1);System.out.println(person2);person2.money.m = 888;person2.id = 2;System.out.println("通过person2修改后的结果");System.out.println(person1);System.out.println(person2);}
}

执行结果:

浅拷贝图解:

3. 深拷贝的介绍和实例

在拷贝一个对象时,除了对基本数据类型的成员变量进行拷贝,对引用类型的成员变量进行拷贝时,创建一个新的对象来保存引用类型的成员变量。简而言之:深拷贝把要复制的对象所引用的对象都复制了一遍。

下面的代码实现了深拷贝;实现person1对象的深拷贝,先用Person tmp引用来保存浅拷贝的结果,通过tmp引用找到money对象,再将money对象拷贝一份,然后赋值给tmp中的money,最后返回tmp即可。这样就将money引用的对象也拷贝了一份,实现了深拷贝,此时person1和person2中的momey指向的是两个不同的对象。

class Money implements Cloneable{public double m = 666;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}}class Person implements Cloneable{public int id;public Money money = new Money();public Person(int id) {this.id = id;}@Overrideprotected Object clone() throws CloneNotSupportedException {//return super.clone();Person tmp = (Person) super.clone();tmp.money = (Money) this.money.clone();return tmp;}@Overridepublic String toString() {return "Person{" +"id=" + id +", money=" + money.m +'}';}
}
public class Test2 {public static void main(String[] args) throws CloneNotSupportedException{Person person1 = new Person(1);Person person2 = (Person) person1.clone();System.out.println("通过person2修改前的结果");System.out.println(person1);System.out.println(person2);person2.money.m = 888;person2.id = 2;System.out.println("通过person2修改后的结果");System.out.println(person1);System.out.println(person2);}
}

执行结果:

深拷贝图解:

4. clone方法总结

java中clone方法是一个浅拷贝,引用类型依然在传递引用。我们可以通过继续调用clone()方法,对 该对象的引用类型变量再实现一次clone()的方法来实现深拷贝。

【Java】深拷贝和浅拷贝,Cloneable接口相关推荐

  1. clone是深拷贝还是浅拷贝_Cloneable接口的作用与探索理解浅拷贝与深拷贝

    导读:本文将主要讨论设计模式--原型模式中,关于cloneable接口及浅拷贝与深拷贝的概念. 原型模式的理解 关于原型模式的理解,我在网上发现一个有趣且助于理解原型模式的例子在这里分享一下:火影忍者 ...

  2. 面试官:Java深拷贝和浅拷贝区别

    文章目录 一.拷贝的引入 (1).引用拷贝 (2).对象拷贝 二.浅拷贝 (1).定义 (2).浅拷贝实例 三.深拷贝 (1).定义 (2).深拷贝实例 一.拷贝的引入 (1).引用拷贝 创建一个指向 ...

  3. java的cloneable_Java的Cloneable接口和clone方法

    1. 克隆的用处 在日常编码中我们经常需要产生某个对象的副本,这里的副本并不是指向同一个对象的不同引用,而是与当前对象状态一模一样的另一个新的对象.如果使用单纯的引用赋值,会发生什么效果呢? 我们可以 ...

  4. 浅谈对java深拷贝与浅拷贝的理解

    java中什么是浅拷贝?什么是深拷贝? 1.拷贝:实现对象复制的方式. 2.浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所 ...

  5. java -- 深拷贝和浅拷贝的区别 如何实现深拷贝和浅拷贝

    文章目录 1. 深拷贝和浅拷贝的区别 1.1 浅拷贝实例 1.1.1 测试1 直接赋值 1.1.2 测试2 改变源对象的值 1.2 深拷贝实例 `这是用于深拷贝的测试类` 1.2.1 方法一: 构造函 ...

  6. Java深拷贝与浅拷贝

    前言 对象拷贝Object Copy是将一个对象的属性,拷贝到另一个相同类型的对象中.拷贝对象主要是为了在新的上下文环境中复用对象的部分或全部数据.其中对象拷贝有3种类型:深拷贝Deep Copy.浅 ...

  7. java深拷贝和浅拷贝_Java 深拷贝浅拷贝 与 序列化

    一.浅拷贝.深拷贝 浅拷贝会对对象中的成员变量进行拷贝:如果是基本类型,拷贝的就是基本类型的值:如果属性是内存地址(引用类型),拷贝的就是内存地址 : 深拷贝,除了基本类型外,引用类型所引用的对象也会 ...

  8. java 深拷贝和浅拷贝

    深拷贝和浅拷贝的问题无非就是拷贝过程中对象的属性是否指向的是同一个对象引用. 浅拷贝的特点: 一:作为基本数据类型来说,例如int ,double等8类数据类型,拷贝过程中肯定是值的传递,修改另一个对 ...

  9. Java clone()方法 与 Cloneable接口详解

    clone()是Object类的一个方法 protected native Object clone() throws CloneNotSupportedException; 调用clone()的条件 ...

  10. java深拷贝和浅拷贝介绍

    浅拷贝概念 深拷贝概念 @Data @Slf4j public class Sheep implements Cloneable {private String name;private int ag ...

最新文章

  1. 从认知学到进化论,详述强化学习两大最新突破
  2. git 操作简明扼要,命令不需要多,够用就行
  3. 前端学习(1948)vue之电商管理系统电商系统之排序
  4. Python 基础入门--简介和环境配置
  5. 用了vscode和clion我都裂开了
  6. mysql php 全是字符串,PHP MySQL中有多个htmlspecialchars字符串
  7. 5-10多分支网络结构
  8. bat脚本更新本地Git仓库
  9. Android开发笔记(八十九)单例模式
  10. 独家披露51CTO被黑过程:数据库已小范围流传
  11. 谷粒商城:05. 分布式组件SpringCloud Alibaba
  12. 不想听别人的建议,就不要问
  13. Matlab 2016a 安装教程
  14. 三星c9000刷android7.0,三星C9 Pro C9000官方原厂rom线刷包刷机包C9000ZCU1CRI1
  15. matlab二重积分有奇异点,用MATLAB计算某些区域上二重积分.pdf
  16. 技术人的未来(三)——红海与蓝海
  17. 通过路由远程计算机重启,路由器如何重启 三种重启路由器的方法【步骤教程】...
  18. 2016年腾讯实习生校园招聘-电面2
  19. 离散数学中的x|y是什么意思?
  20. PHP拼团人数不能超过,怎么解决拼团、抽奖难以凑齐人数这个大问题?

热门文章

  1. python middleware模块_django之中间件middleware
  2. mysql optimizer组件,MySQL Internals Optimizer
  3. MSSQL数据库提示附加数据库错误: 823的修复方法
  4. 在ASP.net中连接Access2007数据库
  5. 用 PyQt 打造具有专业外观的 GUI
  6. 编程语言的终结者:SL (smart language)
  7. c++cout.put 表白
  8. WPF中TextBox只能输入小数
  9. 如何实施 SCRUM ?
  10. 什么是命名空间,为什么要使用命名空间?