clone:用于两个对象有相同的内容时,进行复制操作。

提示:Java中要想自定义类的对象可以被复制,自定义类就必须实现Cloneable中的clone()方法。

浅复制:另一个对象用clone()方法对已经存在的对象进行复制的时候,会改变被复制对象里面所有的内容,换句话说,浅复制就是对对象的复制出现了一些问题。

深复制:另一个对象对已有的对象进行相同的内容复制的时候,不会改变原对象的内容

什么情况下会出现浅复制呢?用下面的例子进行说明:

学生类:

public class Student implements Cloneable {

    private String name;

    private int age;

    private Professor professor;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public Professor getProfessor() {
return professor;
} public void setProfessor(Professor professor) {
this.professor = professor;
} @Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", professor="
+ professor + "]";
} public Object clone() throws CloneNotSupportedException{
return super.clone();
} }

  教授类:

public class Professor {

    private String name;

    private int age;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Professor [name=" + name + ", age=" + age + "]";
} }

 案例一: 

public class ShadowCopy {

    public static void main(String[] args) {
Professor p1 = new Professor();
p1.setName("Professor Zhang");
p1.setAge(30); Student s1 = new Student();
s1.setName("xiao ming");
s1.setAge(18);
s1.setProfessor(p1); System.out.println(s1); try {
Student s2 = (Student) s1.clone();
Professor p2 = s2.getProfessor();
p2.setName("Professor Li");
p2.setAge(45);
s2.setProfessor(p2);
System.out.println("复制后的:s1 = " + s1);
System.out.println("复制后的:s2 = " + s2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} } }

  运行结果1:

1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
3 复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]

  s1的导师为30岁的Professor Zhang,恰巧s2与s1同名同岁,但是s2的导师为45岁的Professor Li,于是我们直接复制s1给s2,再修改下s2的导师的信息。可是,问题出现了,当我们修改了s2的导师后,s2的信息是正确的,但是s1的导师信息也跟着修改了。

案例二:

public class ShadowCopy {

    public static void main(String[] args) {
Professor p1 = new Professor();
p1.setName("Professor Zhang");
p1.setAge(30); Student s1 = new Student();
s1.setName("xiao ming");
s1.setAge(18);
s1.setProfessor(p1); System.out.println(s1); try {
Student s2 = (Student) s1.clone();
s2.setName("xiao hong");
s2.setAge(17);
Professor p2 = s2.getProfessor();
p2.setName("Professor Li");
p2.setAge(45);
s2.setProfessor(p2);
System.out.println("复制后的:s1 = " + s1);
System.out.println("复制后的:s2 = " + s2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} } }

  运行结果二:

1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

  这次,我们在clone后,又修改了s2的name和age,从结果可以看出,s1的name和age并没有因为s2的修改而改变。

  以上出现的两种情况,就是我们所说的浅复制,但我们实际上不希望出现这两种问题,如何解决呢?那我们必须就要进行深复制。接下来就是我要说的深复制

public class Professor implements Cloneable {

    private String name;

    private int age;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Professor [name=" + name + ", age=" + age + "]";
} public Object clone() throws CloneNotSupportedException{
return super.clone();
} }

  

public class Student implements Cloneable {

    private String name;

    private int age;

    private Professor professor;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public Professor getProfessor() {
return professor;
} public void setProfessor(Professor professor) {
this.professor = professor;
} @Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", professor="
+ professor + "]";
} public Object clone() throws CloneNotSupportedException{
Student newStudent = (Student) super.clone();
newStudent.professor = (Professor) professor.clone();
return newStudent;
} }

  再次运行案例一:

1.Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2.复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
3.复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]

  

  再次运行案例二:

1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

  以上就是我们所说的深复制。好好去领悟哦!

  参考博客:https://www.cnblogs.com/acode/p/6306887.html

clone中的浅复制和深复制的更多相关文章

  1. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  2. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  3. Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...

  4. JAVA中浅复制与深复制

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...

  5. Java中的“浅复制”与“深复制”

    复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...

  6. php对象复制、clone、浅复制与深复制实例详解

    php对象复制.clone.浅复制与深复制实例详解 一.用clone(克隆)来复制对象$obj1 = new Object();$obj2 = clone $obj1;clone方法会触发对象里定义的 ...

  7. js中的浅复制和深复制

    浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...

  8. Python中的浅复制、深复制

    参考 https://docs.python.org/3/library/copy.html?highlight=copy%20copy#copy.copy https://en.wikipedia. ...

  9. java基础-浅复制与深复制的理解

    浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...

  10. 也来谈一谈js的浅复制和深复制

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

随机推荐

  1. MyBatis配置数据库连接

    <environments default="default"> <environment id="default"> <tran ...

  2. Java中的集合框架-Collections和Arrays

    上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...

  3. flashback query闪回数据

    误删除了部分重要数据,已提交,需要恢复.首先尝试flashback query闪回数据. 数据库运行在归档模式,首先确认数据库的SCN的变化: SQL> col fscn for 9999999 ...

  4. 给大家推荐一款非常好用的表单验证插件:lr-verify.js

    废话不说,直接上代码说明,1分钟学会: 例: 1.验证配置 $.extend(Verify.types, { "must" : { "verify" : fun ...

  5. 复习Vue

    以前学过vue,但是工作中一直没有用到都忘记了最近在复习下正好做个笔记偶尔看看,(目前常更新,2018年6月25日) 1.指令 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. ...

  6. ElasticSearch优化系列五:机器设置(硬盘、CPU)

    硬盘对集群非常重要,特别是建索引多的情况.磁盘是一个服务器最慢的系统,对于写比较重的集群,磁盘很容易成为集群的瓶颈. 如果可以承担的器SSD盘,最好使用SSD盘.如果使用SSD,最好调整I/O调度算法 ...

  7. java爬虫爬取网页内容前,对网页内容的编码格式进行判断的方式

    近日在做爬虫功能,爬取网页内容,然后对内容进行语义分析,最后对网页打标签,从而判断访问该网页的用户的属性. 在爬取内容时,遇到乱码问题.故需对网页内容编码格式做判断,方式大体分为三种:一.从heade ...

  8. docker 容器模式下部署mysql 主从复制

    1.计划用两台host来部署,分别部署一台 mysql,一主一从,2.配置好主从mysql配置文件,更改文件名即可[client]port = 3306socket = /var/run/mysqld ...

  9. Mac使用bootcamp安装win系统花屏解决方法

    15年11'乞丐版air装win屏幕花屏,很郁闷,先后找了网上很多方法,最终总结出了一个比较折中的方法,不玩游戏不使用大型3D的可以参考. 1 花屏现象 2 解决方法 2.1 禁用驱动 2.2 使用M ...

  10. [Golang学习笔记] 04 程序实体1 变量声明

    变量声明: Go语言的程序实体包含:变量.常量.函数.结构体和接口,是一门静态类型的编程语言. (在声明变量或常量的时候,需要指定类型,或者给予足够信息是的Go语言能够推导出类型) Go语言变量的类型 ...