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

为什么要拷贝?

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

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

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

 

深拷贝与浅拷贝

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

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

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

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

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

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

 

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

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

 

具体呢?

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

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

 

 

代码范例

 

[java]  view plain  copy
  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. }  


测试结果:

[java]  view plain  copy
  1. parent1 = Parent[john===10];  
  2. parent2 = Parent[john===10];  

Parent1被复制了一份。

 

修改下main函数

再执行一次。

测试结果:

 

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

 

 

再修改一下.

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

[java]  view plain  copy
  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. }  
[java]  view plain  copy
  1. <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;">  
  2. </span>  

看main的修改

先copy再设置。

测试结果:

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

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

 

最后,修改一下Clone

[java]  view plain  copy
  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.     }   
[java]  view plain  copy
  1.   

测试结果:

[java]  view plain  copy
  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

 

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值