Kotlin-09.类属性和字段(Properties/Fields)
官方文档: http://kotlinlang.org/docs/reference/properties.html
1.声明类属性
类属性可用关键字var声明为可变的, val声明为只读:
class Address {
var name: String = ...
var street: String = ...
var city: String = ...
}
使用类属性,和使用Java类字段(成员变量)差不多:
fun copyAddress(address: Address): Address {
val result = Address() // Kotlin没有new关键字
result.name = address.name
result.street = address.street
return result
}
2.属性访问器Getters和Setters
声明属性的完整语法:
var <propertyName>[: <PropertyType>] [= <initializer>]
[<getter>]
[<setter>]
其中初始器<initializer>、<getter>和<setter>都是可选的!
如果属性类型:<PropertyType>可从初始器(或者从getter返回值)推断出,也可省略!
1.默认访问器get和set方法
var i = 1 // 推断类型Int、默认getter和setter
val c = 1 // 推断类型Int 、默认getter
2.自定义访问器get和set方法
val isEmpty: Boolean
get() = this.size == 0
var stringRepresentation: String
get() = this.toString()
set(value) {
calxx(value) //按惯例,setter参数名是value,但也可自定义!
}
val isEmpty get() = this.size == 0 // 如能推断出属性类型,则可省略
3.改变访问器get和set可见性或者对其注解,但不改变默认实现:
var setterVisibility: String = "abc"
private set //私有,不改变默认实现
var setterWithAnnotation: Any? = null
@Inject set //注解,不改变默认实现
3.幕后字段和属性
1.隐式幕后字段
Kotlin类不能有字段,但有时在自定义的访问器中需要字段,
为此自动提供隐式幕后字段(backing field),可field标识符访问,
field只能用在属性的访问器中.
var counter = 0 //初始值直接写入到幕后字段
set(value) {
if (value >= 0)
field = value
}
2.显式幕后属性
如果隐式幕后字段不符合需求,可用显式幕后属性(backing property)
private var _table: Map<String, Int>? = null //幕后属性
public val table: Map<String, Int>
get() {
if (_table == null) {
_table = HashMap() //类型参数已推断出
}
return _table ?: throw AssertionError("Set to null by another thread")
} 通过默认getter和setter访问私有属性会被优化,不会引入函数调用开销!
4.属性的初始化
1.编译期常量
属性用const修饰符标记,称为编译期常量Compile-Time Constants,需满足以下要求:
位于顶层或者是object的成员
用 String 或原生类型初始化
没有自定义getter
const val DE: String = "This subsystem is deprecated"
//编译期常量属性可用在注解中
@Deprecated(DE) fun foo(){
}
2.延迟初始化属性
一般情况,属性声明为非空类型,必须在构造函数中初始化。
然而这不方便,为此可用lateinit修饰符非空属性:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // 直接解引用
}
}
lateinit只能用在类体中的var属性,
该属性不能自定义getter和setter方法,
该属性必须是非空类型,不能是原生类型
简书: http://www.jianshu.com/p/3a0ed4118fc9 CSDN博客: http://blog.csdn.net/qq_32115439/article/details/73478111
GitHub博客: http://lioil.win/2017/06/19/Kotlin-properties.html
Coding博客: http://c.lioil.win/2017/06/19/Kotlin-properties.html