Field(幕后屬性)
field:幕后字段是自動生成的,它僅僅可以被用在擁有至少一個默認訪問器 (getter伸刃、setter) 谎砾、或者在自定義訪問器中通過 field 標(biāo)識符修飾的屬性中。幕后字段可以避免訪問器的自遞歸而導(dǎo)致程序崩潰的 StackOverflowError異常捧颅。
為什么會照成這種異常呢景图?
原因在于在kotlin中,任何時候?qū)懥艘粋€變量后面加上等號的代碼時碉哑,這個等號都會被編譯器翻譯成調(diào)用setter方法挚币,比如:var biao:Int = 1亮蒋。任何時候當(dāng)你引用變量時,就會被編譯器翻譯成調(diào)用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}")
當(dāng)我們運行這一段代碼就會出現(xiàn)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方法形成了遞歸調(diào)用薪前,最終程序會因為內(nèi)存溢出而中止程序(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方法調(diào)用了屬性而不是遞歸調(diào)用自身方法润努,從而就不會出現(xiàn)內(nèi)存溢出的異常
其實在kotlin中g(shù)etter和setter是自動生成的,而field也是自動生成示括,所以當(dāng)我們在定義屬性的時候铺浇,除非是要對getter和setter做特殊處理,不然不需要寫出來垛膝。