美文网首页
深拷贝和浅拷贝

深拷贝和浅拷贝

作者: 竖起大拇指 | 来源:发表于2020-09-02 16:37 被阅读0次

我们这里先定义两个类:Student和Major,分别表示学生和所学的专用,二者是包含关系:

   class Major{
      var majorName:String?=null
      var majorId:Long=0
}

class Student{
    var name:String?=null
    var age:Int=0
    var major:Major?=null
}

对象赋值

赋值时日常编程过程中最常见的操作,最简单的比如:

  var student=Student()
   var student1=student

严格来说,这种不算对象拷贝,因为拷贝的仅仅只是引用关系,并没有生成新的实际对象。

浅拷贝

浅拷贝属于对象克隆方式的一种,重要的特性体现在浅字上。主要实现逻辑是 基本类型的字段会复制一份,而引用类型的字段拷贝的仅仅是引用地址,而且该引用地址指向的实际对象空间其实只有一份。

深拷贝

深拷贝相较于浅拷贝,除了值类型字段会复制一份,引用类型字段所指向的对象,会在内存中也创建一个副本。

我们来看看具体的代码实现:

浅拷贝代码实现

open class Student :Cloneable{

    var name:String?=null
    var age:Int=0
    var major:Major?=null


    public override fun clone(): Student {
        return super.clone() as Student
    }

    override fun toString(): String {
        return "Student(name=$name, age=$age, major=$major)"
    }

}

测试代码:

companion object{
        @JvmStatic
        fun main(args: Array<String>) {
            var major=Major()
            major.majorId=6666
            major.majorName="计算机科学与技术"

            var student=Student()
            student.age=20
            student.name="毛大哥"
            student.major=major


            var cloneStudent=student.clone()

            println(cloneStudent==student)
            println("cloneStudent:${cloneStudent}")
            println("student:${student}")

            student.age=22
            major.majorName="计算机应用技术"
            major.majorId=3333

            println("------------after-----------")
            println("cloneStudent:${cloneStudent}")
            println("student:${student}")

        }
    }

运行得到如下结果:

false
cloneStudent:Student(name=毛大哥, age=20, major=com.ble.kotlinscope.clone.Major@5e481248)
student:Student(name=毛大哥, age=20, major=com.ble.kotlinscope.clone.Major@5e481248)
------------after-----------
cloneStudent:Student(name=毛大哥, age=20, major=com.ble.kotlinscope.clone.Major@5e481248)
student:Student(name=毛大哥, age=22, major=com.ble.kotlinscope.clone.Major@5e481248)

从结果可以看出:

  • cloneStudent==student 返回false,说明clone方法的确克隆出了一个新对象;
  • 修改值类型字段并不影响克隆出来的新对象。
  • 修改了student内部的引用对象,克隆对象也改变了,说明内部还是关联在一起,都是同一个对象。

深拷贝代码实现

虽然clone方法可以完成对象的拷贝工作,但是注意:clone()方法默认是浅拷贝行为,若想实现深拷贝需要覆写clone方法实现对象的深度遍历式拷贝。
对于上面的例子,如果想实现深拷贝,首先需要对更深一层的引用类Major做改造,让其也实现Cloneable接口并重写clone方法:

class Major :Cloneable {

    var majorName:String?=null

    var majorId:Int=0

    public open override fun clone(): Major {
        return super.clone() as Major
    }

    override fun toString(): String {
        return "Major(majorName=$majorName, majorId=$majorId)"
    }
}

其次我们还需要在顶层的调用类中重写clone方法,来调用引用类型字段的clone方法来实现深度拷贝。

open class Student :Cloneable{

    var name:String?=null
    var age:Int=0
    var major:Major?=null


    public override fun clone(): Student {
        var student=super.clone() as Student
        student.major=major?.clone()
        return student
    }

    override fun toString(): String {
        return "Student(name=$name, age=$age, major=$major)"
    }

}

上面测试用例不变,运行结果如下:

false
student:Student(name=毛大哥, age=20, major=Major(majorName=计算机科学与技术, majorId=6666))
cloneStudent:Student(name=毛大哥, age=20, major=Major(majorName=计算机科学与技术, majorId=6666))
------------after-----------
student:Student(name=毛大哥, age=22, major=Major(majorName=计算机应用技术, majorId=3333))
cloneStudent:Student(name=毛大哥, age=20, major=Major(majorName=计算机科学与技术, majorId=6666))

很明显,这时候student和cloneStudent两个对象完全独立,不受互相的干扰.

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

  • JavaScript的深拷贝和浅拷贝

    原文 博客原文 大纲 前言1、对深拷贝和浅拷贝的初步认识2、深拷贝和浅拷贝的区别3、浅拷贝存在的缺陷4、深拷贝的实...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

网友评论

      本文标题:深拷贝和浅拷贝

      本文链接:https://www.haomeiwen.com/subject/bedwsktx.html