屬性必須初始化, 如果沒有直接賦值, 就必須寫進構(gòu)造函數(shù)中
聲明在主構(gòu)造函數(shù)中的屬性:
class PfA(val a: Int, var b: Int)
聲明屬性, 然后在次構(gòu)造函數(shù)中初始化或 init 塊中初始化.
class PfB {
var a: Int
val b: Int
val c: Int?
// 次構(gòu)造函數(shù)中不能有 val, var
constructor(a: Int, b: Int, c: Int) {
this.a = a
this.b = b
this.c = c
}
}
class PfBB(a: Int, b: Int) {
val a = a
val b: Int
init {
this.b = b
}
}
直接賦值初始化的屬性:
class PfC {
var a = 0
val b = 1
// val 類型屬性可以這樣初始化, 但是 var 不行!
// 這樣是沒有 backing field 的
val c get() = true
}
完整的屬性聲明語法:
var <propertyName>[: <PropertyType>] [= <property_initializer]
[<getter>]
[<setter>]
初始化表達式, getter, setter 是可選的.
如果屬性類型可以被初始化表達式推斷, 或從 getter 的 return 返回值推斷.
// val 只有 getter, 不能有 setter
// 可以從 getter 返回值推斷類型, 所以類型可以不寫
val allByDefault
get() = 1 // val 可以用 getter, 可以省略初始化表達式和類型
Backing Fields
Kotlin 中默認實現(xiàn)了 java 中的 getter, setter. 但也可以自定義, 修改邏輯.
注意: 如果不在構(gòu)造函數(shù)中初始化, var 變量必須使用初始化表達式, 而 val 變量可以用
getter 代替初始化表達式
// Backing Fields
// 使用 field 標識符, 在 getter setter 內(nèi)可以使用, 用來設(shè)置屬性值.
var getsetvar: Int = 1
set(value) {
field = value + 1
}
// 使用 getter 可以用來做一些邏輯判斷
var getsetvar2: Int = 1 // 這里是初始化
get() {
if(field == 1) {
println("值是 1, 返回 0")
return 0
}
return field
}
set(value) {
field = value + 1
}
測試驗證上面的屬性:
@Test fun testProperties() {
// 初始值是 1
assertEquals(1, address.getsetvar)
// 設(shè)置為 2
address.getsetvar = 2
// setter 會加 1, 所以值應(yīng)該是 3
assertEquals(3, address.getsetvar)
}
@Test fun testProperties2() {
// 初始值是 1, getter 判斷如果等于 1 就返回 0
assertEquals(0, address.getsetvar2)
// 設(shè)置為 3, setter 會加 1, 所以是 4
address.getsetvar2 = 3
assertEquals(4, address.getsetvar2)
}
訪問器 getter setter 的可見性
var setterVisibility: String = "abc"
private set // the setter is private and has the default implementation
var setterWithAnnotation: Any? = null
@Inject set // annotate the setter with Inject
Compile-Time Constants
編譯時常量:
- Top-level or member of an object
- Initialized with a value of type String or a primitive type
- No custom getter
這類屬性可以用在注解中:
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }
延遲初始化屬性(Late-Initialized Property)
用于依賴注入或測試方法中在 @setup, @before 等方法中再進行初始化.
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // dereference directly
}
}