创建对象普遍有两种方式:构建和拷贝。
构建是用new的方式,适合构建初始化状态对象的情况;
拷贝是用clone的方式,适合对象数据完全复制的情况,这里我们主要讨论clone。
以下代码定义Car类,包含price和brand两个基本数据类型的属性。先是构建car1,然后clone得到car2,由于Car类的属性都是基本数据类型,所以不需要考虑深、浅拷贝问题。
//汽车
class Car(var price: Double, val brand: String) : Cloneable {
public override fun clone(): Car {
return super.clone() as Car
}
}
//调用
val car1 = Car(100000.0, "tmw")
val car2 = car1.clone()
val isSame = car1 == car2
println("是否同一个对象$isSame")
//日志
是否同一个对象:false
如果Car中包含引用属性,那就需要深、浅拷贝的问题。
以下代码跟上述类似,只不过增加了一个轮胎属性Tyre。从打印日志可以看到,虽然car1、car2不是同一个对象,但是他们的轮胎属性是同一个,如果修改了car1的轮胎属性,那么car2的也会被修改,这就是浅拷贝问题。
//轮胎
class Tyre(var size: Double, val brand: String)
//汽车
class Car(var price: Double, val brand: String, var tyre: Tyre) : Cloneable {
public override fun clone(): Car {
return super.clone() as Car
}
}
//调用
val car1 = Car(100000.0, "tmw",Tyre(10.0,"普利司通"))
val car2 = car1.clone()
val isSame = car1 == car2
println("是否同一个对象:$isSame")
val isSameTyre = car1.tyre == car2.tyre
println("是否同一个轮胎:$isSameTyre")
//日志
是否同一个对象:false
是否同一个轮胎:true
如果不希望car1、car2的轮胎属性是同一个,那么就需要用深拷贝。其实也很简单,只要Tyre实现Cloneable接口,重写clone()方法,Car类对轮胎属性进行clone即可,具体代码如下:
//轮胎
class Tyre(var size: Double, val brand: String):Cloneable{
public override fun clone(): Tyre {
return super.clone() as Tyre
}
}
//汽车
class Car(var price: Double, val brand: String, var tyre: Tyre) : Cloneable {
public override fun clone(): Car {
val clone = super.clone() as Car
clone.tyre = tyre.clone()
return clone
}
}
集合的深拷贝
当集合的元素为引用类型,需要遍历调用元素的clone方法;
//原始数据
val cars = mutableListOf<Car>()
cars.add(Car(100000.0, "tmw", Tyre(10.0, "普利司通")))
cars.add(Car(120000.0, "tmw", Tyre(10.0, "普利司通")))
cars.add(Car(130000.0, "tmw", Tyre(10.0, "普利司通")))
//clone数据
val cloneCars = mutableListOf<Car>()
cars.forEach {
cloneCars.add(it.clone())
}
当集合元素为基本数据类型,可以直接赋值:
//原始数据
val data = mutableListOf<Long>()
data.add(1)
data.add(2)
data.add(3)
//clone数据
val cloneData = mutableListOf(data)//注意这里直接用data赋值,如果data元素是引用类型,那么这里的拷贝是浅拷贝
总结
1.深、浅拷贝区别在于:内部的引用属性clone前后是否是同一个;
2.mutableListOf(data),内部是浅拷贝,不适合data元素是引用类型的情况;
3.对象中有枚举属性,不需要做特殊处理,底层clone会处理。
以上分析有不对的地方,请指出,互相学习,谢谢哦!
网友评论