什么是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有字段 ,这是一个比领域更高层次的概念。
有两种类型的属性:一种具有后台字段,另一种没有。
具有后台字段的属性将以字段的形式存储该值。 该字段使存储在内存中的价值成为可能。 这种属性的一个例子是Pair
的first
和second
属性。 该属性将改变Pair
的内存表示。
没有后台字段的属性将不得不以其他方式存储它们的值,而不是直接将其存储在内存中。 它必须从其他属性或对象本身进行计算。 此属性的一个示例是List
的indices
扩展属性,它不受字段支持,而是基于size
属性的计算结果。 所以它不会改变List
的内存表示(因为Java是静态类型的,所以它根本无法做到)。
备份字段非常适合在状态更改时运行验证或触发事件。 想想你把代码添加到Java setter / getter的时代。 在类似的情况下,备份字段会很有用。 当你需要控制或者对setter / getters有可见性时,你可以使用后备字段。
当为字段赋予字段名称本身时,实际上是调用setter(即set(value)
)。 在你的例子中, this.counter = value
会递归到set(value)中,直到我们溢出堆栈。 使用field
绕过setter(或getter)代码。
- Hibernate @OneToMany连接表抛出StackOverflowException
- java.lang.OutOfMemoryError:pthread_create(1040KB堆栈)失败:请尝试
- Kotlin中活动与片段之间的交流
- 我怎样才能明确表示RxJava中Flowable的完成?
- 是否有可能限制开关使用kotlin / JAVA中的特定情况?
- 导入和锯齿实践
- 使用Amazon AWS Cognito`.well-known / jwks.json`数据无法base64解码一些字段
- 在BottomsheetDialog中使用setcontentview时,会出现类似“以下函数都不能用提供的参数调用”的错误
- Jackson @JsonProperty注释用于kotlin数据类的使用