浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢?

要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制。复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等。我们可以发现,复制操作后可以得到两份相同的东西,即复制由一变为二了。下面来看一个例子:

public class User{

     private int age;

     public int getAge(){

          return age;

     }

}

User user1 = new User();

User user2 = user1;

上面把user2 = user1属于复制吗?显然,这种操作不属于复制,因为user2=user1仅仅是把user1的引用赋值给user2,此时user1与user2指向内存中同一个对象,所以没有一变成二。在Java中的复制需要得到两个相同的对象,而不是指两个相同的引用。

如果要得到一个真正的复制对象,需要自行实现clone()方法,clone()方法存在于Object类中,默认被所有的类继承,方法签名如下:

protected native Object clone() throws CloneNotSupportedException;

由于clone()方法是用protected修饰的,不能在类外被调用,所以我们如果要复制一个对象,就需要在类中覆盖clone()方法,并把修饰符升级为public,而且被复制的类需要实现Cloneable接口,否则调用clone()方法时会抛出CloneNotSupportedException异常。

public class User implements Cloneable{

     public User(int age){

          this.age = age;

     }

     private int age;

     public int getAge(){

          return age;

     }

     public Object clone() {

          User user = null;

          try{

               user = super.clone();

          }catch(Exception e){

          }

          return user;

     }

}

User usr1 = new User();

User usr2 = usr1.clone();

System.out.println(usr1==usr2); 

System.out.println(usr1.getAge()+", "+ usr2.getAge());

######结果

false

, 

说明clone方法得到了两个对象,且变量相同。上面的例子说明的仅仅是浅复制的情况,下面再来看一个例子:

public class Phone{

     private String name;

     public Phone(String name){

          this.name = name;

     }

     public void setName(String name){

          this.name = name;

     }

     public String getName(){

          return this.name;

     }

}

public class User implements Cloneable{

     public User(int age){

          this.age = age;

          this.phone = new Phone("华为");

     }

     private int age;

     public Phone phone;

     public int getAge(){

          return age;

     }

     public Object clone() {

          User user = null;

          try{

               user = super.clone();

          }catch(Exception e){

          }

          return user;

     }

}

上面代码定义了User类和Phone类,其中User类有一个Phone类的变量,下面调用这两个类:

User usr1 = new User();

User usr2 = usr1.clone();

System.out.println(usr1==usr2);

System.out.println(usr1.getAge()+", "+ usr2.getAge());

System.out.println(usr1.phone.getName()+", "+ usr2.phone.getName());

usr1.phone.setName("小米");

System.out.println(usr1.phone.getName()+", "+ usr2.phone.getName());

###结果

false

, 

华为, 华为

小米, 小米

有没有发现一些问题了?修改usr1的变量phone的name的值,修改为“小米”,但是usr2的变量phone的name的值也变为“小米”了。这说明了usr1与usr2的phone变量引用的Phone对象是同一个的,上面的这种复制就是浅复制,浅复制没有复制引用类型的变量。

为了达到深复制,我们需要把类中的引用类型也变成可复制化,即实现Cloneable接口,如下:

public class Phone implements Cloneable{

     private String name;

     public Phone(String name){

          this.name = name;

     }

     public void setName(String name){

          this.name = name;

     }

     public String getName(){

          return this.name;

     }

     public Object clone(){

          Phone phone = null;

          try{

               phone = super.clone();

          }catch(Exception e){

          }

          return phone;

     }

}

public class User implements Cloneable{

     public User(int age){

          this.age = age;

          this.phone = new Phone("华为");

     }

     private int age;

     public Phone phone;

     public int getAge(){

          return age;

     }

     public Object clone() {

          User user = null;

          try{

               user = super.clone();

          }catch(Exception e){

          }

          user.phone = (Phone)phone.clone();

          return user;

     }

}

由上可以总结,浅复制会把基本数据类型的变量都复制一份,对于引用类型变量只是仅仅对引用进行复制,没有对引用的内存对象进行复制;而深复制会把对象复制一份,也会把对象的引用变量指向的对象复制一份,深复制复制更加彻底。

文章同步发布在朗度云网站上,传输门:

http://www.wolfbe.com/detail/201608/271.html

java基础-浅复制与深复制的理解的更多相关文章

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

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

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

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

  3. Java里的浅复制与深复制

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

  4. JAVA中浅复制与深复制

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

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

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

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

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

  7. js的浅复制和深复制

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

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

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

  9. iOS 浅复制和深复制的深层理解,含示例

    转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...

随机推荐

  1. css中postion的fixed与absolute区别详解

    fixed:固定定位,参照位置是浏览器窗口的左上角,即坐标点为(0px, 0px) absolute:绝对定位,参展位置是离当前元素最近的定位方式为fixed,absolute,relative的祖先 ...

  2. 定时导出Oracle数据表到文本文件的方法

    该实例实现了通过windows定时任务来实现了将数据库中指定数据表数据导出为txt文本格式.其思路是通过可执行的bat文件去调用导出数据脚本,然后再在windows定时任务中调用该bat文件来实现.该 ...

  3. 解决faststone capture在台式机上录制屏幕视频没有声音的问题

    点击屏幕录像机: 在弹出的屏幕录像机窗口中选择录制音频,然后点击选项按钮: 在弹出的选项按钮中选择视频选项,将所有的多选框都选中,注:最后一个选项录制windows XP的工具提示最好也选上,我发现如 ...

  4. C++与正态分布

    正态分布(Normal distribution)又名高斯分布(Gaussiandistribution).若随机变量X服从一个数学期望为μ.方差为σ^2的高斯分布,记为N(μ,σ^2).其概率密度函 ...

  5. scala的下划线

    1.作为“通配符”,类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就 ...

  6. 3.4html学习笔记之表格

    <table border=""style="border-collapse:collapse"> <caption>表格</ca ...

  7. AngularJS特性

    如果你不熟悉什么是Angular.js的话,小编我强烈推荐你阅读 Javascript教程:AngularJS的五个超酷特性.简单来说Angular.js是google开发者设计和开发的一套前端开发框 ...

  8. 根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第2版)

             目录:                 第1版:http://blog.csdn.net/vipbooks/article/details/51912143              ...

  9. Phong光照以及其他

        在说光照之前,有必要先弄清法线的变换,假设Mworld 将物体的定点一一变换到世界空间,如果我们对法线实施同样的变化,,以为能将法线变换到世界空间,但世界上变换之后的法线不再与表面垂直,就像下 ...

  10. 移动端 viewport设置

    <meta name="viewport" content="" /> width [pixel_value | device-width] wid ...