Kotlin向我解释了Backing Fields

时间:2017-12-06 16:25:06

标签: android kotlin kotlin-android-extensions

我一直在看Kotlin官方教程。我遇到了一个名为支持字段

的主题

它说,

  

Kotlin中的类不能有字段。但是,有时在使用自定义访问器时需要有一个支持字段。出于这些目的,Kotlin提供了一个自动支持字段,可以使用字段标识符访问:

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

我从this official link

获得了上述内容

我的问题是,“字段”是否指向计数器变量?

有人可以为我提供一个支持领域的例子,还是用一个理解词来形容我?

4 个答案:

答案 0 :(得分:10)

考虑这个课程

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;
      }
   }
}

答案 1 :(得分:6)

$originalArray = array( 'first', 'second', 'third', 'fourth' ); $newArray= $originalArray; shuffle( $newArray); for ($i=0; $i<2; $i++) { echo $newArray[$i]; } 关键字允许您在自定义设置器中指定值。在kotlin field中会调用counter = 3。所以,如果你要定义

set(3)

它将以递归方式调用自身,直到您的堆栈已满并且您的进程崩溃。 var counter=0 set(value){ counter = value } 关键字直接指定值,而无需再次调用setter。

答案 2 :(得分:3)

  

Backing Field只是一个为属性生成的字段   仅在类中使用至少一个的默认实现时才在类中   访问者

仅当属性使用getter / setter的默认实现时才会生成Backing字段。如果您使用Java的透视图看到以下代码。看起来很正确。但是在“kotlin”中它会抛出异常。

  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“}”时,递归callhappens和编译器抛出异常异常,因为我们在setter中调用setter。

此问题的解决方案是用户支持字段。在Kotlin中,可以使用访问者内部的“field”关键字访问支持字段。请查看下面更正的代码段。

 class User{ 
      var firstName : String get() = field 
      set(value) {
           field = value
      } 
      var lastName : String get() = field 
      set(value) {
           field = value} 
      }
 }

答案 3 :(得分:1)

如何运作,让我们通过一个例子来理解,考虑一下这个

class Person {
   var name: String = ""
}

如果未指定任何内容,则属性(名称)将使用默认的getter和setter。当然,它可以 被修改为运行您需要的任何自定义行为,而无需更改 现有代码:

因此,如果要将自定义行为设置为name属性,而不是将上面的类修改为此

class Person {

   var name: String = ""
   get() = field.toUpperCase()
   set(value) {
     field = "Name: $value"
  }


}

如果属性需要在自定义getter或setter中访问自己的值(如此) 例),它需要创建支持字段。可以使用field,a访问它 保留字,并在编译器发现时自动创建 它被使用了。