科特林向我解释了“背景场”

我一直在看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} } } 

希望对你清楚。 如果你需要更多的帮助问我..谢谢