Kotlin-数据类
来源:互联网 发布:人工智能产业高峰论坛 编辑:程序博客网 时间:2024/06/07 11:42
概述
在开发过程中,经常会创建一些数据里,其没有任何逻辑功能,仅仅来用来保存数据。在Kolin中,将这些类统一称为数据类,用关键字data标记。
data class User(val name: String, val age: Int)
编译器会根据主构造器中声明的全部属性, 自动推断产生以下成员函数:
- equals()/hashCode()函数对,
- toString() 函数, 输出格式为 “User(name=John, age=42)” ,
- componentN() 函数群, 这些函数与类的属性对应, 函数名中的数字 1 到 N, 与属性的声明顺序一致,
- copy() 函数
如果在该数据类或者基类中重写了以上某个成员函数,将不会再自动推断,以重写的为准。
数据类的声明条件
- 主构造器至少要有一个参数;
- 主构造器的所有参数必须标记为 val 或 var ;
- 数据类不能是抽象类、open 类、封闭(sealed)类、或内部(inner)类;
- 数据类不能继承自任何其他类(但可以实现接口);
如果数据类有无参构造函数,需将主构造函数中,将成员属性初始化。
data class User(val name: String = "", val age: Int = 0)
对象复制
之前提到,JVM会自动为一个数据类生成copy()函数。copy()到底用来干啥的?copy()是对对象的浅拷贝还是深拷贝?带着这些疑问往下看。
data class Person(var name: String, var age: Int) {}data class MyInfo(val no: Int, var person: Person) { override fun hashCode(): Int { return super.hashCode() }}fun main(args: Array<String>) { var per0: Person = Person("A", 20) var per1: Person = per0.copy(age = 15) println("------- Log0 -------") println("per0: $per0") println("per1: $per1") println("------- Log1 -------") per1.name = "B" println("per0: $per0") println("per1: $per1") println("------- Log2 -------") var info0: MyInfo = MyInfo(1, per0) var perAA = Person("AA", 30) var info1: MyInfo = info0.copy(no = 2) var info2: MyInfo = info0.copy(person = perAA) println("info0: $info0") println("info1: $info1") println("------- Log3 -------") info1.person.name = "C" println("info0: $info0") println("info1: $info1") println("------- Log4 -------") println("info0: $info0") println("info1: $info1") println("info2: $info2") println("------- Log5 -------") info2.person.name = "AC" println("info0: $info0") println("info1: $info1") println("info2: $info2") println("perAA: $perAA")}// Log打印------- Log0 -------per0: Person(name=A, age=20)per1: Person(name=A, age=15)------- Log1 -------per0: Person(name=A, age=20)per1: Person(name=B, age=15)------- Log2 -------info0: MyInfo(no=1, person=Person(name=A, age=20))info1: MyInfo(no=2, person=Person(name=A, age=20))------- Log3 -------info0: MyInfo(no=1, person=Person(name=C, age=20))info1: MyInfo(no=2, person=Person(name=C, age=20))------- Log4 -------info0: MyInfo(no=1, person=Person(name=C, age=20))info1: MyInfo(no=2, person=Person(name=C, age=20))info2: MyInfo(no=1, person=Person(name=AA, age=30))------- Log5 -------info0: MyInfo(no=1, person=Person(name=C, age=20))info1: MyInfo(no=2, person=Person(name=C, age=20))info2: MyInfo(no=1, person=Person(name=AC, age=30))perAA: Person(name=AC, age=30)
先创建了两个数据类Person和MyInfo,而MyInfo类中有一个Person成员属性,现分别创建了Person和MyInfo实例,并分别运用了其copy()函数,生成了一个新的对象。
从Log0和Log1可以看出,通过copy()得到的对象修改其基本类型的属性时,对原对象并没有影响。
从Log2和Log3的对比及Log4和Log5的对比,在执行copy()函数时,对于引用类型,其引用对象将指向被复制过的新对象,并不是新创建了一个对象。
也就是说,copy()函数实现的功能是复制一个对象,然后修改其一部分属性,但保持其他属性保持不变。copy并不是简单的复制,它会创建新的对象,对于基本类型的属性,其值会被拷贝并赋值,但是对于引用类型,其只是将其地址传递过去,还是进行浅拷贝,并没有创建新的对象。怎么觉得copy()实际上是浅拷贝和深拷贝的综合呢,好不理解哦。
对于“=”号赋值,大家都很清楚的是进行了浅拷贝,从Log1中,就可以即使基本数据类型,在新的对象的基本类型属性进行赋值时,也会影像原值的属性。
var per0: Person = Person("A", 20)var per1: Person = per0------- Log0 -------per0: Person(name=A, age=20)per1: Person(name=A, age=20)------- Log1 -------per0: Person(name=B, age=20)per1: Person(name=B, age=20)
“=”号赋值和copy()在执行机制上还是有区别的。在对copy使用时,还是要注意对引用类型的浅拷贝,稍微留神就犯大错误了。。。
数据的解构
前面提到了,JVM会数据类生成一些列的组件函数(componentN() 函数群),其与这些函数与类的属性对应, 函数名中的数字 1 到 N, 与属性的声明顺序一致,有了这些组件函数, 就可以在解构声明中使用数据。
val jane = Person("Jane", 35)val (n, a) = janeprintln("$n, $a years of age") // 打印结果将是 "Jane, 35 years of age"
- Kotlin-数据类
- Kotlin -- 数据类
- Kotlin数据类(八)
- Kotlin-数据类
- kotlin学习day5:数据类
- Kotlin 第十章:数据类
- Kotlin for Android(七)Kotlin数据类和Gson
- Kotlin-13.数据类(data class)
- # Kotlin学习之-5.6 数据类
- Kotlin-属性-接口-修饰符-数据类
- kotlin中的数据类data class
- Kotlin之数据类解构申明
- Kotlin基础教程-数据对象
- Kotlin解析数据(九)
- Kotlin开发Android笔记8:Kotlin数据类及json解析
- Kotlin-类
- Kotlin 类
- [kotlin系列] (s2_3)扩展、数据类、密封类
- (赶快收藏吧)前端开发必会的二十五个知识点
- Xutils请求网络
- springMVC项目基础配置加载完成执行事件
- Eclipse与MyEclipse的选择问题
- java.lang.OutOfMemoryError异常解决方法
- Kotlin-数据类
- Xml与Java对象之间的解析转换
- Scala 基础总结
- Mac下安装svn并且检出项目
- Github Reset
- Unsolicited response received on idle HTTP channel starting with "[]\n"; err=<nil>
- 位段与联合,枚举类型
- Android打开各种类型的文件方法总结
- NetWork——描述一次完整的网络请求过程