clone中的浅复制和深复制
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中的浅复制和深复制的更多相关文章
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...
- JAVA中浅复制与深复制
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- Java中的“浅复制”与“深复制”
复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...
- php对象复制、clone、浅复制与深复制实例详解
php对象复制.clone.浅复制与深复制实例详解 一.用clone(克隆)来复制对象$obj1 = new Object();$obj2 = clone $obj1;clone方法会触发对象里定义的 ...
- js中的浅复制和深复制
浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...
- Python中的浅复制、深复制
参考 https://docs.python.org/3/library/copy.html?highlight=copy%20copy#copy.copy https://en.wikipedia. ...
- java基础-浅复制与深复制的理解
浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...
- 也来谈一谈js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...
随机推荐
- EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果,及FromSql方法使用讲解
EF Core中: 如果调用Queryable.Count等聚合方法,不会导致DbContext跟踪(track)任何实体. 此外调用Queryable.Join方法返回的匿名类型也不会被DbCont ...
- alibaba之Nacos
本文为转载文章 原文链接:https://windmt.com/2018/11/09/intro-to-spring-cloud-alibaba-nacos/ 上个月最后一天的凌晨,Spring Cl ...
- Java中的类与对象
一.类与对象的概念 1.类:类是一组相同属性.方法的对象的集合:对象是类的具体化. 2.对象具有类所有的特征,类拥有的,对象就拥有. 3.类与对象他们的关系是相对的. 类有什么特点 1) 类是对象的类 ...
- Python绘制奥运五环
绘制奥运五环主要涉及到Python中的turtle绘图库运用: turtle.forward(distance) 向当前画笔方向移动distance像素长度 turtle.backward(dista ...
- 20181031noip模拟赛T1
思路: 我们会发现不合法的位置只有两种情况 要么在前半边,要么在后半边 那么,我们将序列劈两次 使两次的长度分别为: (n为偶数时要特判一下,因为根本不可能) (n/2),(n/2+1) (n/2+1 ...
- ORACLE->SQL*Loader[20180712]
https://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_concepts.htm#g1013706 SQL*Loader将外部 ...
- Mave实战(1)——Maven介绍
目录 1. Maven介绍 1.1. 何为Maven 1.1.1. Maven是优秀的构建工具 1.1.2. Maven不仅仅是构建工具 1. Maven介绍 1.1. 何为Maven Maven是一 ...
- react-navigation的超级大坑
本文针对react-navigation^3.0.0版本,版本不对的话,请不要看本文,直接看官方英文文档 最近一直在学习RN,没找到什么好的视频,所以一直看文档,一路上来虽然遇到一些乱七八糟的bu ...
- Redis(一):NoSQL入门和概述
NoSQL入门和概述目录导航: NoSQL入门概述 3V+3高 当下的NoSQL经典应用 NoSQL数据模型简介 NoSQL数据库的四大分类 在分布式数据库中CAP原理CAP+BASE NoSQL 入 ...
- laravel5.5源码笔记(一、入口应用的初始化)
laravel的项目入口文件index.php如下 define('LARAVEL_START', microtime(true)); require __DIR__.'/../vendor/auto ...