声明
var 代表可变。
val 代表只读。后面加冒号可以指定类型。必须初始化,不像 java 有默认值。
var a:String = "a"复制代码
可以用?表示可以为 null
var a:String? = null复制代码
Getter 和 Setter
声明属性的完整语法。包括类型指定,初始化值,getter,setter。默认会自动实现 getter setter。
var[: ] [= ] [ ] [ ]复制代码
可以不直接初始化,但必须在构造中初始化。
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) { // 每次读值都会走get(), 写值后读的还是 get 的值 println(a) propertiesAndFields.a = "qweqwe" println(a)}输出:wenchiehqweqwewenchieh复制代码
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 Propertiesprivate var aTable: Map? = nullval table: Map 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
在初始化之前被访问了,会抛出一个特定的未初始化错误。