什么是Kotlin后台?

作为Java开发人员,后台字段的概念对我来说有点陌生。 鉴于:

class Sample { var counter = 0 // the initializer value is written directly to the backing field set(value) { if (value >= 0) field = value } } 

这个后盾有什么好处? Kotlin的文档说: Kotlin中的类不能有字段。 但是,使用自定义访问器时有时需要有后台字段 。 为什么? 在setter中使用属性名称本身的区别是什么,例如。

  class Sample { var counter = 0 set(value) { if (value >= 0) this.counter = value // or just counter = value? } } 

因为,如果你没有field关键字,你将无法真正地设置/获取get()set(value) 。 它使您能够访问自定义访问器中的后台字段。

这是您的示例的等效Java代码:

 class Sample { private int counter = 0; public void setCounter(int value) { if (value >= 0) setCounter(value); } public int getCounter() { return counter; } } 

显然这并不好,因为二传手本身就是一个无限递归,从不改变任何东西。 记住在kotlin中,只要你写foo.bar = value ,它将被翻译成setter调用而不是PUTFIELD


编辑:Kotlin有属性,而Java有字段 ,这是一个比领域更高层次的概念。

有两种类型的属性:一种具有后台字段,另一种没有。

具有后台字段的属性将以字段的形式存储该值。 该字段使存储在内存中的价值成为可能。 这种属性的一个例子是Pairfirstsecond属性。 该属性将改变Pair的内存表示。

没有后台字段的属性将不得不以其他方式存储它们的值,而不是直接将其存储在内存中。 它必须从其他属性或对象本身进行计算。 此属性的一个示例是Listindices扩展属性,它不受字段支持,而是基于size属性的计算结果。 所以它不会改变List的内存表示(因为Java是静态类型的,所以它根本无法做到)。

备份字段非常适合在状态更改时运行验证或触发事件。 想想你把代码添加到Java setter / getter的时代。 在类似的情况下,备份字段会很有用。 当你需要控制或者对setter / getters有可见性时,你可以使用后备字段。

当为字段赋予字段名称本身时,实际上是调用setter(即set(value) )。 在你的例子中, this.counter = value会递归到set(value)中,直到我们溢出堆栈。 使用field绕过setter(或getter)代码。