`

浅拷贝与深拷贝的实现

 
阅读更多

需要实现对某个对象的拷贝,做了个小例子,便于日后复习。需要拷贝的对象属于Student类型,包含两个字段sex和userName,而userName是属于引用类型。对应的类是Name,该类包含firstName和lastName。代码如下:

   class Name {

       private String firstName ="";

       private String lastName = "";

 

       public void setLastName(String lastName) {

           this.lastName = lastName;

       }

       public String getLastName() {

           return lastName;

       }

       public void setFirstName(String firstName) {

           this.firstName = firstName;

       }

       public String getFirstName() {

           return firstName;

       }

    }

 

   public class Student {

       private String sex = "";

       private Name userName = null;

 

       public void setUserName(Name userName) {

           this.userName = userName;

       }

       public Name getUserName() {

           return userName;

       }

       public void setSex(String sex) {

           this.sex = sex;

       }

       public String getSex() {

           return sex;

       }

   }

当在main方法中写如下代码:

  public static void main(String[] args) throws Exception {

Name name = new Name();

       name.setFirstName("Zhang");

       name.setLastName("San");   

Student student1 = new Student();

       student1.setSex("");

       student1.setUserName(name);

  }

当执行完student1的赋值后,存储的情况大致如下:

 

 

 

需要一个Student类型的对象student2,并且student2从student1复制而来,涉及到两种复制模式,

一是浅拷贝:即将student1的所有的成员变量的值拷贝给student2,但是对于引用类型则是拷贝的地址引用,所有完成浅拷贝后student2与student1中的引用类型的变量userName还是指的同一个对象,当student1的成员变量userName中firstName的值发生改变时,student2的userName中的firstName也会受到影响。浅拷贝后内存中的存储大致如下:

由图容易看出student1与student2对象的userName属性对应的是同一个对象,所有当userName对象中的firstName或是lastName发生改变时,两个对象的对于的属性的值都会受到影响。

第二种拷贝为深拷贝,即对象中的引用类型的变量的值也做拷贝,拷贝后不指向同一对象,这样的话成员变量值的改变互相不会受影响,深拷贝后的内存存储大致如下:

明白了深拷贝与浅拷贝的不同之处后,我们来分别实现两种不同的拷贝。

1,对于浅拷贝可以通过Object对象的clone方法实现。需要被拷贝的对象要实现Cloneable接口,实现clone方法,对应我们的Student类只需要做一些修改即可。public class Student implements Cloneable {

       private String sex = "";

       private Name userName = null;

 

       public void setUserName(Name userName) {

           this.userName = userName;

       }

       public Name getUserName() {

           return userName;

       }

       public void setSex(String sex) {

           this.sex = sex;

       }

       public String getSex() {

           return sex;

       }

      

       @Override

       protected Object clone() throws CloneNotSupportedException {

           return super.clone();

       }

}

 生成studnet1对象后,只需要使用以下语句即可复制生成student2对象:

 Student student2 = (Student)student1.clone();

如果借助apache的beanutils还可以通过以下方式实现浅拷贝

Student student2 = (Student)BeanUtils.cloneBean(student1);

2,对应深拷贝则需要通过序列化的方式实现

 

public class Student implements Cloneable,Serializable {

       private static final long serialVersionUID = 5932252818552269951L;

       private String sex = "";

       private Name userName = null;

       public void setUserName(Name userName) {

           this.userName = userName;

       }

       public Name getUserName() {

           return userName;

       }

       public void setSex(String sex) {

           this.sex = sex;

       }

       public String getSex() {

           return sex;

       }

      

       @Override

       protected Object clone() throws CloneNotSupportedException {

           return super.clone();

       }

      

       public Student deepClone() throws Exception {

           Student s = null;

           ByteArrayOutputStream baos = new ByteArrayOutputStream();

           ObjectOutputStream oos = new ObjectOutputStream(baos);

           oos.writeObject(this);

           oos.flush();

           oos.close();

          

           byte[] arrByte = baos.toByteArray();

           ByteArrayInputStream bais = new ByteArrayInputStream(arrByte);

           ObjectInputStream ois = new ObjectInputStream(bais);

           s = (Student)ois.readObject();

           ois.close();

           return s;

       }

    }

调用deepClone方法就可以实现深拷贝。

Student student2 = student1.deepClone();

可以根据实际的需要选择浅拷贝或是深拷贝。

分类: Java
分享到:
评论

相关推荐

    C#中的浅拷贝和深拷贝

    ### C#中的浅拷贝与深拷贝 在C#编程语言中,对象的复制是一项基本而重要的操作。根据复制的方式不同,可以分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。这两种复制方式各有其特点和适用场景。 #### 值类型...

    C++深拷贝浅拷贝

    根据提供的标题、描述和部分无法识别的内容,我们将围绕“C++深拷贝与浅拷贝”的主题进行深入探讨。在C++编程语言中,深拷贝(Deep Copy)与浅拷贝(Shallow Copy)是对象复制时经常遇到的概念。它们在内存管理和...

    python浅拷贝、深拷贝

    在Python中,浅拷贝(shallow copy)和深拷贝(deep copy)是用于创建...使用方式:在Python中,可以使用不同的方法实现浅拷贝和深拷贝。例如,对于可变对象,可以使用copy模块的copy函数实现浅拷贝,使用copy.deepco

    C++之深拷贝和浅拷贝

    解决浅拷贝问题的方法是实现一个深拷贝的拷贝构造函数。深拷贝不仅复制指针本身,还会复制指针指向的数据,为每个对象分配独立的内存空间。这样,在析构函数中释放内存时,每个对象释放的是其独立分配的内存,从而...

    js浅拷贝与深拷贝的区别和实现方式.md

    js浅拷贝与深拷贝的区别和实现方式.md

    Java中的深拷贝(深复制)和浅拷贝(浅复制) 示例代码

    为了理解深拷贝(深复制)和浅拷贝(浅复制),我们需要首先了解Java对象内存的分配方式以及引用的概念。 1. **对象复制的基础** 在Java中,当我们创建一个对象时,系统会在内存中为该对象分配一块空间,存储它的...

    C#浅拷贝深拷贝

    `CloneDemo`可能是一个示例项目,它包含了关于如何在C#中实现浅拷贝和深拷贝的代码。通过分析和运行这个项目,你可以更深入地理解这两种拷贝方式的区别和应用场景。 总结起来,C#中的浅拷贝和深拷贝是处理对象复制...

    Java Clone深拷贝与浅拷贝的两种实现方法

    Java Clone 深拷贝与浅拷贝的两种实现方法 Java Clone 是 Java 语言中的一种复制对象的机制,它可以将一个对象的所有属性和状态复制到另一个对象中,实现对象的深拷贝和浅拷贝。下面我们将讨论 Java 中的深拷贝和浅...

    深入理解JavaScript中的深拷贝与浅拷贝:实现方法与应用场景

    本文将详细探讨JavaScript中的深拷贝和浅拷贝,包括它们的定义、实现方法以及在不同场景下的应用。 深拷贝和浅拷贝是JavaScript中处理对象和数组复制的两种基本方法。选择使用哪一种取决于具体的需求和场景。浅拷贝...

    深拷贝拷贝的是内容,浅拷贝拷贝的是指针

    ### 深拷贝与浅拷贝的概念及应用 #### 一、深拷贝与浅拷贝的区别 在计算机编程领域中,深拷贝(Deep Copy)与浅拷贝(Shallow Copy)是两种常见的对象复制方法。这两种方法在处理复杂数据结构(如数组、列表等)时...

    C#浅拷贝和深拷贝数据

    // 深拷贝实现 MyClass copy = new MyClass(); copy.Value = this.Value; if (this.Reference != null) { copy.Reference = new MyReferenceType(this.Reference); } return copy; } } ``` 3. 使用序列化...

    JS浅拷贝和深拷贝原理与实现方法分析

    JavaScript中的浅拷贝和深拷贝是两种不同的对象复制方式,它们在处理复杂对象时有着显著的区别。在JavaScript中,对象是引用类型,因此当一个对象被复制时,如果不进行特殊处理,复制的只是指向原对象的引用,而非...

    浅拷贝+深拷贝.rar

    不过,为了防止“钻石问题”(即当一个对象同时被浅拷贝和深拷贝构造时,可能会产生两个析构函数被调用的情况),通常建议遵循“Rule of Three/Five/Zero”,根据情况实现拷贝构造函数、赋值运算符和析构函数。...

    浅拷贝深拷贝之jQuery中的$.extend分析

    这篇博客“浅拷贝深拷贝之jQuery中的$.extend分析”深入探讨了`$.extend`在浅拷贝和深拷贝场景下的工作原理,这对于理解JavaScript对象的复制机制至关重要。 浅拷贝是指创建一个新对象,然后将源对象的引用属性复制...

    通过源码分析iOS中的深拷贝与浅拷贝

    在iOS开发中,深拷贝和浅拷贝是两个关键概念,它们涉及到对象复制时内存管理的细节。本文将从源码角度深入解析这两种拷贝方式。 首先,我们需要明确深拷贝和浅拷贝的基本定义。浅拷贝,也称为指针拷贝,意味着拷贝...

    java深入理解浅拷贝和深拷贝

    浅拷贝(Shallow Copy)指的是创建一个新的对象,该对象与原对象具有相同的引用,也就是说,它们共享同一块内存空间。如果对象包含的是基本类型的数据,那么这些数据会被完全复制到新对象中。然而,如果对象中包含的...

    深拷贝浅拷贝.zip

    拷贝分为两种主要类型:浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。本篇文章将深入探讨这两种拷贝方式,并通过实际的代码示例来展示它们的区别和实现。 浅拷贝是指创建一个新对象,这个新对象引用的是原始对象...

    js深拷贝与浅拷贝详解以及例子.pdf

    JS 深拷贝与浅拷贝详解以及例子 深拷贝与浅拷贝是 JavaScript 开发中常见的概念,分别对应着不同的拷贝方式。在本文中,我们将详细介绍浅拷贝和深拷贝的概念、特点、实现方法和实例。 一、浅拷贝 浅拷贝只拷贝一...

    Python 深拷贝和浅拷贝详解

    深拷贝(Deep Copy)则更加彻底,它不仅创建一个新的对象,而且会递归地复制原对象中的所有可变元素,确保新对象与原对象及其子对象之间没有任何关联。这意味着即使原对象中的可变元素被修改,深拷贝的对象也不会受...

    JavaScript中的深拷贝与浅拷贝:技术解析与代码实现

    浅拷贝和深拷贝各有适用场景。浅拷贝适用于只需复制对象第一层属性且不涉及修改引用类型属性的场景,而深拷贝适用于需要完全独立的数据副本,尤其是处理嵌套对象或数组时。在选择拷贝方法时,应根据实际需求和性能...

Global site tag (gtag.js) - Google Analytics