• Java深拷贝和浅拷贝的区别


    浅拷贝

    被复制的对象的所有的变量都与原对象有相同的值,而所有的引用对象仍然指向原来的对象。换言之,浅拷贝 不复制引用对象。

    复制代码
     1 class Experience {
     2     private String skill;
     3     public void setSkill(String skill){
     4         this.skill = skill;
     5     }
     6     public void setExperience(String skill){
     7         this.skill = skill;
     8     }
     9 
    10     @Override
    11     public String toString() {
    12         return skill;
    13     }
    14 }
    15 
    16 public class CloneTest implements Cloneable{
    17 
    18     private int age ;
    19     private Experience experience;   
    20 
    21     public CloneTest(){
    22         this.age = 10;
    23         this.experience = new Experience();
    24     }
    25     public Experience getExperience() {
    26         return experience;
    27     }
    28     public void setExperience(String skill){
    29         experience.setExperience(skill);
    30     }
    31     public void show(){
    32         System.out.println(experience.toString());
    33     }
    34     public int getAge() {
    35         return age;
    36     }
    37     @Override
    38     protected Object clone() throws CloneNotSupportedException {
    39         return (CloneTest) super.clone();
    40     }
    41 }
    42 //测试类
    43 class MianTest{
    44 
    45     public static void main(String[] args) throws CloneNotSupportedException {
    46         CloneTest test = new CloneTest();
    47         test.setExperience("我是小明,我精通Java,C++的复制粘贴");
    48         test.show();
    49         CloneTest cloneTest = (CloneTest) test.clone();
    50         cloneTest.show();
    51         cloneTest.setExperience("我是小明的副本,我精通Java,C++");
    52         cloneTest.show();
    53         test.show();
    54         System.out.println(cloneTest.getAge());
    55     }
    56 }
    复制代码

    输出的结果:

    我是小明,我精通Java,C++的复制粘贴
    我是小明,我精通Java,C++的复制粘贴
    我是小明的副本,我精通Java,C++
    我是小明的副本,我精通Java,C++
    10

    从结果中不难看出,拷贝的副本改变了Experience的skill属性,原类中的skill属性打印出来也是修改后的结果,说明引用 类型的拷贝没有将对象拷贝,引用的指向还是原类中的指向

    深拷贝

    除了被复制的对象的所有变量都有原来对象的值之外,还把引用对象也指向了被复制的新对象

    复制代码
     1 class Experience implements Cloneable{
     2     private String skill;
     3     public void setSkill(String skill){
     4         this.skill = skill;
     5     }
     6     public void setExperience(String skill){
     7         this.skill = skill;
     8     }
     9 
    10     @Override
    11     public String toString() {
    12         return skill;
    13     }
    14 
    15     @Override
    16     protected Object clone() throws CloneNotSupportedException {
    17         return super.clone();
    18     }
    19 }
    20 
    21 public class CloneTest implements Cloneable{
    22 
    23     private int age ;
    24     private Experience experience;
    25 
    26     public CloneTest(){
    27         this.age = 10;
    28         this.experience = new Experience();
    29     }
    30     public Experience getExperience() {
    31         return experience;
    32     }
    33     public void setExperience(String skill){
    34         experience.setExperience(skill);
    35     }
    36     public void show(){
    37         System.out.println(experience.toString());
    38     }
    39     public int getAge() {
    40         return age;
    41     }
    42     @Override
    43     protected Object clone() throws CloneNotSupportedException {
    44         CloneTest o = (CloneTest) super.clone();
    45         o.experience = (Experience) o.getExperience().clone();
    46         return o;
    47     }
    48 }
    49 class MianTest{
    50 
    51     public static void main(String[] args) throws CloneNotSupportedException {
    52         CloneTest test = new CloneTest();
    53         test.setExperience("我是小明,我精通Java,C++的复制粘贴");
    54         test.show();
    55         CloneTest cloneTest = (CloneTest) test.clone();
    56         cloneTest.show();
    57         cloneTest.setExperience("我是小明的副本,我精通Java,C++");
    58         cloneTest.show();
    59         test.show();
    60         System.out.println(cloneTest.getAge());
    61     }
    62 }
    复制代码

    输出的结果:

    我是小明,我精通Java,C++的复制粘贴
    我是小明,我精通Java,C++的复制粘贴
    我是小明的副本,我精通Java,C++
    我是小明,我精通Java,C++的复制粘贴
    10

    可以看出和第一次的结果不同了。

    o.experience =(Experience) o.getExperience().clone();

    加了这句之后效果不同的。说明实现了深拷贝,原引用对象也复制过来了

     

     

     

     

     

  • 相关阅读:
    synchronized 到底该不该用?
    线上Java程序占用 CPU 过高,请说一下排查方法?
    『JVM』我不想知道我是怎么来滴,我就想知道我是怎么没滴
    Golang 实现 Redis(8): TCC分布式事务
    Golang 实现 Redis(7): 集群与一致性 Hash
    Golang 实现 Redis(6): 实现 pipeline 模式的 redis 客户端
    LSM 树详解
    uni-app subNVue 原生子窗体简单使用案例(app端)
    日计不足涓滴成河-自定义响应结果格式化器
    RTT之软件包
  • 原文地址:https://www.cnblogs.com/651434092qq/p/12120179.html
Copyright © 2020-2023  润新知