Java基础-深拷贝和浅拷贝的区别

为什么要拷贝?

Java克隆是为了得到一个 完全一致的对象。

相同点:对象完全一样。这包括里头所有的变量,对象。

不同点:对象的内存地址不一样。

 

深拷贝与浅拷贝

一般来说,拷贝的类型分为 深拷贝与浅拷贝。

|—————————————————————————————|

| 深拷贝:引用对象的值等信息,复制一份一样的。             |

| 浅拷贝:只复制引用,另一处修改,你当下的对象也会修改。   |

|—————————————————————————————|

网上有这样的描述,以上描述不科学

 

从字面上理解更好。
浅拷贝---拷贝的级别浅。

深拷贝---拷贝级别更深。

 

具体呢?

浅拷贝---能复制变量,如果对象内还有对象,则只能复制对象的地址

深拷贝---能复制变量,也能复制当前对象的 内部对象

 

 

代码范例

  1.     public class mytest {
  2.         public static void main(String[] args) {
  3.             Parent item1 = new Parent("john", 10);
  4.             Parent item2 = item1.clone();
  5.             
  6.             System.out.println("parent1 = " + item1.toString());
  7.             System.out.println("parent2 = " + item2.toString());
  8.         }
  9.         
  10.         public static class Parent implements Cloneable{
  11.             String name = "";
  12.             int age = 0;
  13.             Parent (String n, int age){
  14.                 this.name = n;
  15.                 this.age = age;
  16.             }
  17.      
  18.             public void setName(String na) {
  19.                 name = na;
  20.             }
  21.             @Override
  22.             protected Parent clone() {
  23.                 Parent clone = null;
  24.                 try {
  25.                     clone = (Parent) super.clone();
  26.                 } catch (CloneNotSupportedException e){
  27.                     throw new RuntimeException(e); // won't happen
  28.                 }
  29.                 
  30.                 return clone;
  31.              }
  32.             
  33.             public String toString() {
  34.                 return "Parent[" + name + "===" + age + "];";
  35.             }
  36.         }
  37.     }

 

测试结果:

  1.     parent1 = Parent[john===10];
  2.     parent2 = Parent[john===10];

Parent1被复制了一份。

 

修改下main函数

再执行一次。

测试结果:

 

发现parent1被修改了,但是parent2并未收到影响。

 

 

再修改一下.

添加一个内部类son,并加到parent里头去。

  1.     public class mytest {
  2.         。。。。。。。。    
  3.         public static class Parent implements Cloneable{
  4.             String name = "";
  5.             int age = 0;
  6.             Son theson;
  7.             Parent (String n, int age){
  8.                 this.name = n;
  9.                 this.age = age;
  10.             }
  11.      
  12.             public void setName(String na) {
  13.                 name = na;
  14.             }
  15.             
  16.             public void setSon(Son s) {
  17.                 theson = s;
  18.             }
  19.             @Override
  20.             protected Parent clone() {
  21.                 Parent clone = null;
  22.                 try {
  23.                     clone = (Parent) super.clone();
  24.                 } catch (CloneNotSupportedException e){
  25.                     throw new RuntimeException(e); // won't happen
  26.                 }
  27.                 
  28.                 return clone;
  29.              }
  30.             
  31.             public String toString() {
  32.                 return "Parent[" + name + "===" + age + "];" + "---Son:"+ (theson != null ? theson.name : "null");
  33.             }
  34.         }
  35.         public static class Son implements Cloneable {
  36.             String name = "";
  37.             int age = 0;
  38.             Son (String n, int age){
  39.                 this.name = n;
  40.                 this.age = age;
  41.             }
  42.      
  43.             public void setName(String na) {
  44.                 name = na;
  45.             }
  46.             @Override
  47.             protected Son clone() {
  48.                 Son clone = null;
  49.                 try {
  50.                     clone = (Son) super.clone();
  51.                 } catch (CloneNotSupportedException e){
  52.                     throw new RuntimeException(e); // won't happen
  53.                 }
  54.                 
  55.                 return clone;
  56.              }
  57.             
  58.             public String toString() {
  59.                 return "Son[" + name + "===" + age + "];";
  60.             }
  61.         }
  62.     }
  63.     <span style="mso-spacerun:'yes';font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;">
  64.     </span>

看main的修改

先copy再设置。

测试结果:

可以看到parent1与parent2中的son都变了。

可见,浅拷贝---只是将 内部对象的地址保存。。。。

 

最后,修改一下Clone

  1.             @Override
  2.             protected Parent clone() {
  3.                 Parent clone = null;
  4.                 try {
  5.                     clone = (Parent) super.clone();
  6.                 } catch (CloneNotSupportedException e){
  7.                     throw new RuntimeException(e); // won't happen
  8.                 }
  9.                 clone.theson = theson.clone();
  10.                 return clone;
  11.              } 


测试结果:

  1.     parent1 = Parent[alice-john===10];---Son:alice---john's son
  2.     parent2 = Parent[john===10];---Son:john'son<span style="mso-spacerun:'yes';font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:'Times New Roman';font-size:10.5000pt;mso-font-kerning:1.0000pt;"> </span>

结果达到了我预计的结果。。。

 
小结

浅拷贝与深拷贝,一字之差,主要表明了拷贝的层次差别。

Object的clone方法,必须要实现Cloneable。

表明了,clone方法的实现要程序员自己来。。。

而深浅拷贝只是术语的区别。。。你怎么实现的就是怎么个定义。

1. 必须实现Cloneable

2. 要深拷贝,得注意对象的内部对象,也需要clone
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值