kotlin学习---Field

kotlin学习—Field

Field(幕后属性)

field:幕后字段是自动生成的,它仅仅可以被用在拥有至少一个默认访问器 (getter、setter) 、或者在自定义访问器中通过 field 标识符修饰的属性中。幕后字段可以避免访问器的自递归而导致程序崩溃的 StackOverflowError异常。
为什么会照成这种异常呢?
原因在于在kotlin中,任何时候写了一个变量后面加上等号的代码时,这个等号都会被编译器翻译成调用setter方法,比如:var biao:Int = 1。任何时候当你引用变量时,就会被编译器翻译成调用getter方法。让我们看看代码和反编译成java之后的代码是如何的

class TestKotlinClass {
    var biao:Int = 1
    get() = biao
    set(value) {
        if (value >1){
            biao = value
        }else{
            biao = 1
        }
    }
}   

var testKotlinClass = TestKotlinClass()
testKotlinClass.biao = 2
println("了解class-->${testKotlinClass.biao}")

当我们运行这一段代码就会出现StackOverflowError异常。看看反编译之后的Java代码(点击as的菜单栏 Tools/Kotlin/Show Kotlin Betycode/Decompile可以获取)

public final class TestKotlinClass {
   public final int getBiao() {
      return this.getBiao();
   }

   public final void setBiao(int value) {
      if (value > 1) {
         this.setBiao(value);
      } else {
         this.setBiao(1);
      }
   }
}

看到这里就很清晰了,在getter和setter里面我们都用到了biao属性,这时候在getter、setter方法形成了递归调用,最终程序会因为内存溢出而中止程序(StackOverflowError异常)
让我们看看使用了field的代码

var biao:Int = 1
    get() = field
    set(value) {
        if (value >1){
            field = value
        }else{
            field = 1
        }
    }

反编译成Java

private int biao = 1;
   public final int getBiao() {
      return this.biao;
   }
   public final void setBiao(int value) {
      if (value > 1) {
         this.biao = value;
      } else {
         this.biao = 1;
      }
   }

可以看出field让getter和setter方法调用了属性而不是递归调用自身方法,从而就不会出现内存溢出的异常

其实在kotlin中getter和setter是自动生成的,而field也是自动生成,所以当我们在定义属性的时候,除非是要对getter和setter做特殊处理,不然不需要写出来。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值