Yud*_*rya 73 android kotlin kotlin-android-extensions
作为一名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?
        }
    }
gle*_*e8e 71
因为,如果你没有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;
    }
}
显然这不好,因为setter只是一个infinte recursion本身,从来没有改变任何东西.记得在kotlin中,无论何时你写foo.bar = value它都会被翻译成一个setter call而不是a PUTFIELD.
编辑:Java有字段,而Kotlin有属性,这是一个比字段更高级别的概念.
有两种类型的属性:一种具有支持字段,一种没有.
具有支持字段的属性将以字段的形式存储该值.该字段使存储值可以存储在内存中.这种属性的一个例子是first和的second属性Pair.该属性将改变内存中的表示形式Pair.
没有后备字段的属性必须以其他方式存储其值,而不是直接将其存储在内存中.它必须从其他属性或对象本身计算.此类属性的一个示例是indices扩展属性List,它不是由字段支持,而是基于size属性的计算结果.所以它不会改变内存中的表示List(它根本不能做,因为Java是静态类型的).
the*_*ger 15
最初,我也很难理解这个概念.所以让我借助一个例子向你解释一下.
考虑一下这个Kotlin课程
class DummyClass {
    var size = 0;
    var isEmpty
        get() = size == 0
        set(value) {
            size = size * 2
        }
}
现在,当我们查看代码时,我们可以看到它有2个属性,即 - size(使用默认访问器)和isEmpty(使用自定义访问器).但它只有1个字段即size.要了解它只有1个字段,让我们看看这个类的Java等价物.
转到工具 - > Kotlin - >在Android Studio中显示Kotlin ByteCode.单击"反编译".
   public final class DummyClass {
   private int size;
   public final int getSize() {
      return this.size;
   }
   public final void setSize(int var1) {
      this.size = var1;
   }
   public final boolean isEmpty() {
      return this.size == 0;
   }
   public final void setEmpty(boolean value) {
      this.size *= 2;
   }
}
显然,我们可以看到java类只有getter和setter函数isEmpty,并且没有声明它的字段.类似地,在Kotlin中,没有属性的支持字段isEmpty,因为该属性根本不依赖于该字段.因此没有支持领域.
现在让我们删除自定义的getter和setter isEmpty属性.
class DummyClass {
    var size = 0;
    var isEmpty = false
}
而上述类的Java等价物是
public final class DummyClass {
   private int size;
   private boolean isEmpty;
   public final int getSize() {
      return this.size;
   }
   public final void setSize(int var1) {
      this.size = var1;
   }
   public final boolean isEmpty() {
      return this.isEmpty;
   }
   public final void setEmpty(boolean var1) {
      this.isEmpty = var1;
   }
}
在这里,我们看到了两个领域size和isEmpty.isEmpty是一个支持字段,因为isEmpty属性的getter和setter 依赖于它.
备份字段适用于运行验证或触发状态更改事件.想想您将代码添加到Java setter/getter的时间.在类似的场景中,支持字段会很有用.当您需要控制或了解setter/getter时,您可以使用支持字段.
在使用字段名称本身分配字段时,您实际上正在调用setter(即set(value)).在你拥有的例子中,this.counter = value将递归到set(value)直到我们溢出堆栈.使用field绕过setter(或getter)代码.
| 归档时间: | 
 | 
| 查看次数: | 8919 次 | 
| 最近记录: |