科特林向我解释了“背景场”
我一直在看Kotlin官方教程。 我遇到了一个名为Backing Fields的主题
它说,
Kotlin的课程不能有字段。 但是,使用自定义访问器时有时需要有后台字段。 为了这些目的,Kotlin提供了一个可以使用字段标识符访问的自动后台字段:
var counter = 0 // the initializer value is written directly to the backing field set(value) { if (value >= 0) field = value }
我从这个官方链接得到了上述
我的问题是,是“领域”指向计数器variables?
有人能给我提供一个支持领域的例子,或者用一个理解的词来形容我吗?
考虑这个类
class SomeClass { var counter: Int = 0 set(value) { if (value >= 0) field = value } }
在Android Studio中,进入Main menu -> Tools -> Kotlin -> Show Kotlin Bytecode
,然后点击Kotlin字节码面板中的Decompile
。
你看到的是Java中的等效代码。
public final class SomeClass { private int counter; public final int getCounter() { return this.counter; } public final void setCounter(int value) { if(value >= 0) { this.counter = value; } } }
field
关键字允许您在自定义setter中分配一个值。 在kotlin counter = 3
将调用set(3)
。 所以如果你想定义
var counter=0 set(value){ counter = value }
它会递归调用自己,直到你的堆栈已满,你的进程崩溃。 field
关键字直接赋值,而不用再次调用setter。
如何运作,让我们通过一个例子来理解,考虑一下
class Person { var name: String = "" }
如果没有指定,则属性( 名称 )使用默认的getter和setter。 当然,可以修改它以运行所需的任何自定义行为,而无需更改现有代码:
所以如果要设置自定义行为来命名属性比我们修改上面的类到这个
class Person { var name: String = "" get() = field.toUpperCase() set(value) { field = "Name: $value" } }
如果属性需要在自定义getter或setter中(如本例中)那样访问自己的值,则需要创建一个后台字段 。 它可以通过使用字段,一个保留字来访问,并且在编译器发现它被使用时会自动创建。
Backing Field只是一个字段,只有当它使用至少一个访问器的默认实现时,才会为类中的某个属性生成
仅当属性使用getter / setter的默认实现时,才会生成备份字段。 如果您以Java
角度看下面的代码。 它看起来正确。 然而在“kotlin”它会抛出exception。
class User{ var firstName : String //backing field generated get() = firstName set(value) { firstName = value } var lastName : String //backing field generated get() = lastName set(value) { lastName = value } val name : String //no backing field generated get() = "{$firstName $lastName}" var address : String = "XYZ" //^because there is no default //^implementation of an accessor }
在Kotlin上面的代码片断会抛出StackOverflow,因为当我们访问或设置属性“first-name”或“last name”时,默认访问器将被调用。 所以在Kotlin中,“user.firstName =”value“”与Java的“user.setFirstName(”value“)”相同。
所以当调用“set(value){firstName =”value“}”时,递归调用将会产生一个exceptionexception,因为我们在setter中调用setter。
解决此问题的方法是用户支持字段。 在Kotlin中,可以使用访问器中的“field”关键字访问后台字段。 看看下面更正的代码片段。
class User{ var firstName : String get() = field set(value) { field = value } var lastName : String get() = field set(value) { field = value} } }
希望对你清楚。 如果你需要更多的帮助问我..谢谢