为什么属性初始化器不会调用自定义setter?
从Kotlin文档中,允许自定义setter:
class Test {
var stringRepresentation: String
get() = field
set(value) {
setDataFromString(value)
}
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
但是你不能拥有一个没有自定义getter的自定义setter(并且从init
块初始化):
class Test {
// Compilation error: "Property must be initialized"
var stringRepresentation: String
set(value) {
setDataFromString(value)
}
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
虽然你可以有一个自定义的getter没有自定义setter,但没有问题在这里:
class Test {
var stringRepresentation: String
get() = field
init {
stringRepresentation = "test"
}
private fun setDataFromString(value: String) { }
}
那么为什么你不能使用一个自定义setter来初始化init
块中的属性,为什么init
块会在属性初始值设定项直接分配的时候调用自定义setter,绕过了自定义setter?
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被初始化为它的类的“一个” opon实例,而不调用setter。 然后调用init块并使用setter将值设置为“b” 。 然后使用setter来“c” 。
链接地址: http://www.djcxy.com/p/94259.html上一篇: Why don't property initializers call a custom setter?
下一篇: Xcode 8.2 & 8.1 crashes when enlarging any view in storyboard