声明
var 代表可变。
val 代表只读。
后面加冒号可以指定类型。必须初始化,不像 java 有默认值。
var a:String = "a"
复制代码
可以用?表示可以为 null
var a:String? = null
复制代码
Getter 和 Setter
声明属性的完整语法。包括类型指定,初始化值,getter,setter。默认会自动实现 getter setter。
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
复制代码
可以不直接初始化,但必须在构造中初始化。
class PropertiesAndFields {
private val a: String?
private val simple: Int?
init {
a = null
simple = 3
}
}
复制代码
get() 和 set() 的意思很简单,当读取 a 的值时会调用 get(), 给 a 写值时,会调用 set()
var a: String?
get() = "wenchieh"
set(value) = println(value)
fun main(a: Array<String>) {
// 每次读值都会走get(), 写值后读的还是 get 的值
println(a)
propertiesAndFields.a = "qweqwe"
println(a)
}
输出:
wenchieh
qweqwe
wenchieh
复制代码
val 只有 get(),因为它是只读的。
1.1 之后可以根据 get() 类型自动推测。省略类型,不能初始化。
val isEmpty
get() = this.size == 0 // 推测为 Boolean 类型
复制代码
var 必须定义 get() set()。set 中不能引用 field。才不必初始化。
var isEmpty2
get() = a.size == 0
set(value) {
println("asdad")
}
复制代码
给默认的 set get 添加注解和可见性修饰符:
var b = 2
private set
@InitConciseSyntax.Inject get
复制代码
Backing Fields
Kotlin 中没有字段,只有属性。默认都有 getter getter。
在 getter setter 中,Kotlin 提供一个 field
关键字的字段。
var backingField: Int = 2 // field 被初始化为2
get() {
if (field >= 0) {
return field
}
return -1
}
set(value) {
if (value >= 0)
field = value
}
复制代码
如果使用了 field
就会生成。没使用就没有这个字段。
val greeting: String
get() = "hello"
复制代码
val 只有 getter, get() 没有用到 field
字段,不初始化是可以的。var 有 seteer 和 getter,set() 和 get() 都没有用到 field
时才可以不用初始化。
// get 用到了 field 必须初始化,field 才有值
val greeting: String
get() = field
复制代码
var greeting: String
get() = "hello"
set(value) { println(value)}
复制代码
Backing Properties
如果不适合使用 Backing Field,可以使用 Backing Properties。和 Java 类似
// Backing Properties
private var aTable: Map<String, Int>? = null
val table: Map<String, Int>
get() {
if (aTable == null) {
aTable = HashMap()
}
return aTable ?: throw AssertionError("Set to null by another thread")
}
复制代码
编译时常量
在编译时已知其值的属性可以使用 const
修饰符标记为编译时常量。const
只能修饰 val
类似于 Java 的 static final
.
编译时常量需满足:
- 在top-level声明的 或者 是一个object的成员(Top-level or member of an object)
- 以String或基本类型进行初始化
- 没有自定义getter
可以在注解中使用这些属性。
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprected(SUBSYSTEM_DEPRECATED) fun foo() { ... }
复制代码
延迟初始化
使用 lateinit
修饰符,延迟加载。
需满足条件:
- 只能修饰 var
- 不能用于主构造函数中
- 不能为 null
- 类型不能为基本类型
- 属性不能有自定义的 getter setter
如果 lateinit
在初始化之前被访问了,会抛出一个特定的未初始化错误。