官方文檔: http://kotlinlang.org/docs/reference/properties.html
1.聲明類屬性
類屬性可用關(guān)鍵字var聲明為可變的, val聲明為只讀:
class Address {
var name: String = ...
var street: String = ...
var city: String = ...
}
使用類屬性,和使用Java類字段(成員變量)差不多:
fun copyAddress(address: Address): Address {
val result = Address() // Kotlin沒(méi)有new關(guān)鍵字
result.name = address.name
result.street = address.street
return result
}
2.屬性訪問(wèn)器Getters和Setters
聲明屬性的完整語(yǔ)法:
var <propertyName>[: <PropertyType>] [= <initializer>]
[<getter>]
[<setter>]
其中初始器<initializer>面粮、<getter>和<setter>都是可選的!
如果屬性類型:<PropertyType>可從初始器(或者從getter返回值)推斷出,也可省略!
1.默認(rèn)訪問(wèn)器get和set方法
var i = 1 // 推斷類型Int漫玄、默認(rèn)getter和setter
val c = 1 // 推斷類型Int 、默認(rèn)getter
2.自定義訪問(wèn)器get和set方法
val isEmpty: Boolean
get() = this.size == 0
var stringRepresentation: String
get() = this.toString()
set(value) {
calxx(value) //按慣例,setter參數(shù)名是value,但也可自定義奔坟!
}
val isEmpty get() = this.size == 0 // 如能推斷出屬性類型,則可省略
3.改變?cè)L問(wèn)器get和set可見(jiàn)性或者對(duì)其注解,但不改變默認(rèn)實(shí)現(xiàn):
var setterVisibility: String = "abc"
private set //私有,不改變默認(rèn)實(shí)現(xiàn)
var setterWithAnnotation: Any? = null
@Inject set //注解,不改變默認(rèn)實(shí)現(xiàn)
3.幕后字段和屬性
1.隱式幕后字段
Kotlin類不能有字段,但有時(shí)在自定義的訪問(wèn)器中需要字段,
為此自動(dòng)提供隱式幕后字段(backing field),可field標(biāo)識(shí)符訪問(wèn),
field只能用在屬性的訪問(wèn)器中.
var counter = 0 //初始值直接寫(xiě)入到幕后字段
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() //類型參數(shù)已推斷出
}
return _table ?: throw AssertionError("Set to null by another thread")
}
通過(guò)默認(rèn)getter和setter訪問(wèn)私有屬性會(huì)被優(yōu)化,不會(huì)引入函數(shù)調(diào)用開(kāi)銷(xiāo)!
4.屬性的初始化
1.編譯期常量
屬性用const修飾符標(biāo)記,稱為編譯期常量Compile-Time Constants,需滿足以下要求:
位于頂層或者是object的成員
用 String 或原生類型初始化
沒(méi)有自定義getter
const val DE: String = "This subsystem is deprecated"
//編譯期常量屬性可用在注解中
@Deprecated(DE) fun foo(){
}
2.延遲初始化屬性
一般情況,屬性聲明為非空類型,必須在構(gòu)造函數(shù)中初始化。
然而這不方便,為此可用lateinit修飾符非空屬性:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // 直接解引用
}
}
lateinit只能用在類體中的var屬性,
該屬性不能自定義getter和setter方法,
該屬性必須是非空類型,不能是原生類型
簡(jiǎn)書(shū): http://www.reibang.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