来自Kotlin 文档 https://kotlinlang.org/docs/reference/properties.html#getters-and-setters,允许自定义设置器:
class Test {
var stringRepresentation: String
get() = field
set(value) {
setDataFromString(value)
}
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
但是,如果没有自定义 getter,则无法拥有自定义 setter(并从init
block):
class Test {
// Compilation error: "Property must be initialized"
var stringRepresentation: String
set(value) {
setDataFromString(value)
}
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
尽管您可以在没有自定义 setter 的情况下使用自定义 getter,但这里没有问题:
class Test {
var stringRepresentation: String
get() = field
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
那么为什么不能使用自定义 setter 和从内部初始化的属性呢?init
阻止,为什么init
块调用自定义设置器,而属性初始值设定项直接分配,绕过自定义设置器?
class Test {
var stringRepresentation: String = "" // Does not call custom setter
set(value) {
setDataFromString(value)
}
init {
stringRepresentation = "test" // Calls custom setter
}
private fun setDataFromString(value: String) { }
}
属性初始值设定项不会调用自定义设置器,因为它们的目的是提供默认值。
与 Java 不同,在 Kotlin 中,不仅局部变量必须在首次访问之前初始化,类属性也必须在首次访问之前初始化。
在 Java 中这是有效的。
public class Test {
public String str;
public static void main(String[] args) {
System.out.println(new Test().str);
}
}
在 Kotlin 中则不然。
class Parent {
var str: String?
}
fun main(args: Array<String>) {
Parent().str
}
因此,自定义 setter 需要通过属性初始值设定项或构造函数来初始化其属性。看一下下面的例子。
class Test {
var stringRepresentation: String = "a" // Default value. Does not call custom setter
get() = field
set(value) {
println("Setting stringRepresentation property to %s. Current value is %s.".format(value, field))
field = setDataFromString(value)
}
init {
this.stringRepresentation = "b" // Calls custom setter
}
private fun setDataFromString(value: String): String {
println("Setting stringRepresentation property to %s.".format(value))
return value
}
}
fun main(args: Array<String>) {
Test().stringRepresentation = "c" // Calls custom setter
}
属性 stringRepresentation 初始化为"a"无需调用 setter 即可实例化其类。
然后调用 init 块并将值设置为"b"使用设置器。
然后到"c"使用设置器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)