[Kotlin]深入理解backing field

最近劲妙,一個同學突然問到一個問題:為什么擴展屬性不能直接進行初始化湃鹊?針對這個問題,官方文檔有一段簡短的解釋镣奋,翻譯成中文就是:實際上币呵,擴展并不會真正地往類中插入成員變量。因此侨颈,我們沒有一個有效的方式讓一個擴展屬性擁有backing field余赢,這就是擴展屬性不允許被初始化的原因。大多數(shù)同學看到上面這一段話肯定是一頭霧水哈垢,但我們抓到了一個關(guān)鍵詞backing field妻柒。解釋這個問題,其實就是理解backing field的本質(zhì)耘分。

backing field是什么

這個單詞不好翻譯举塔,很多譯文將其翻譯為幕后屬性幕后字段。的確求泰,有那么一層意思央渣,但總感覺不是很貼切。因此渴频,這篇文章我們始終使用這個官方英文單詞來表示芽丹。

在Kotlin語言中,如果在類中定義一個成員變量卜朗,Kotlin將自動生成默認setter/getter方法拔第。而Kotlin提供了一種非常特殊的方式聲明setter/getter方法:

  var name: String? = null
        set(value) {
            field = value
        }
        get() = field

這里我們直接使用了本次的主人公field字段,如果不使用會怎樣呢场钉?你應(yīng)該很自然地想到這樣處理:

  var name: String? = null
        set(value) {
            name = value
        }
        get() = name

實例化這個類楼肪,然后對當前實例的name屬性進行賦值并取值。Oops...結(jié)果惹悄,你會發(fā)現(xiàn)春叫,無論是取值還是賦值都出現(xiàn)遞歸調(diào)用。

這是為什么呢?是的暂殖,聰明的你肯定已經(jīng)想到了价匠。我們在setter方法中對name賦值的時候會調(diào)用自身,結(jié)果出現(xiàn)了遞歸調(diào)用呛每,getter方法同理踩窖。

這個時候救世主backing field降臨了。backing field的作用域僅僅存在于當前屬性的setter/getter方法中晨横,它就像當前屬性的影子一樣洋腮。因此,我認為翻譯成影子屬性也許更合適手形。

理解了backing field的意圖之后啥供,我們再來解釋為什么擴展屬性不能直接初始化。這個時候库糠,使用正向思維直接推導就可以了伙狐。假設(shè)對Dog擴展了一個屬性color,假設(shè)可以直接初始化瞬欧,聲明看起來應(yīng)該是這樣:

var Dog.color: String = "#ff0000"

注意:Kotlin語言針對屬性默認會生成setter/getter方法贷屎,其默認實現(xiàn)是這樣的:

var Dog.color: String = "#ff0000"
        set(value) field = value
        get() = field

我們看到了熟悉的老朋友field,由于擴展屬性并不會真正地在類中插入字段艘虎,那這個field自然就無處安放了唉侄。有人說,可以放在全局嗎野建?

當然不行美旧!field是什么?field是當前屬性的影子贬墩。而當前屬性是與某個實例一一對應(yīng)的榴嗅。這就是為什么官方文檔說,沒有一個有效的辦法使擴展屬性擁有field字段陶舞。結(jié)果就尷尬了嗽测!聲明擴展屬性的時候我們就不得不自己實現(xiàn)setter/getter方法。

這里大家還可以做一個簡單的實驗肿孵,使用上述的定義方式唠粥,看看最終Kotlin幫忙生成的setter/getter代碼是什么。這里我直接將實驗結(jié)果展示給大家看:

 @Nullable
  private String name;
  
  @Nullable
  public final String getName() {
    return this.name;
  }
  
 // 這里的value對應(yīng)你在set方法中自定義的參數(shù)名稱
  public final void setName(@Nullable String value) {
    this.name = value;
  }

簡單總結(jié)

至此停做,整個問題的謎底已經(jīng)揭曉了晤愧。由于Java語言中不存在backing field這樣一個屬性,難免會導致理解上的問題蛉腌。這個時候可以使用逆推 + 猜想的方式尋找答案官份。文章最后我給出了Kotlin幫忙生成的代碼片段只厘,這是怎么做到的呢?其實很簡單舅巷,先使用Kotlin編譯器將Kotlin代碼編譯成Java字節(jié)碼羔味,再用JD-GUI反編譯class文件就可以看到最終生成的Java代碼了。


我是歐陽鋒钠右,我熱愛Kotlin赋元。如果你喜歡我的文章,請在文章下方留下你愛的小心心飒房。如果你不喜歡我的文章搁凸,請先喜歡上我的文章。然后再留下愛的小心心狠毯!

下次文章再見护糖,拜拜!


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垃你,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子喂很,更是在濱河造成了極大的恐慌惜颇,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件少辣,死亡現(xiàn)場離奇詭異凌摄,居然都是意外死亡,警方通過查閱死者的電腦和手機漓帅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門锨亏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忙干,你說我怎么就攤上這事器予。” “怎么了捐迫?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵乾翔,是天一觀的道長。 經(jīng)常有香客問我施戴,道長反浓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任赞哗,我火速辦了婚禮雷则,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肪笋。我一直安慰自己月劈,他們只是感情好度迂,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著艺栈,像睡著了一般英岭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上湿右,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天诅妹,我揣著相機與錄音,去河邊找鬼毅人。 笑死吭狡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的丈莺。 我是一名探鬼主播划煮,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缔俄!你這毒婦竟也來了弛秋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤俐载,失蹤者是張志新(化名)和其女友劉穎蟹略,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遏佣,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡挖炬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了状婶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片意敛。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖膛虫,靈堂內(nèi)的尸體忽然破棺而出草姻,到底是詐尸還是另有隱情,我是刑警寧澤稍刀,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布碴倾,位于F島的核電站,受9級特大地震影響掉丽,放射性物質(zhì)發(fā)生泄漏跌榔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一捶障、第九天 我趴在偏房一處隱蔽的房頂上張望僧须。 院中可真熱鬧,春花似錦项炼、人聲如沸担平。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽暂论。三九已至面褐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間取胎,已是汗流浹背展哭。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闻蛀,地道東北人匪傍。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像觉痛,于是被迫代替她去往敵國和親役衡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 人生苦多薪棒,快來 Kotlin 手蝎,快速學習Kotlin! 什么是Kotlin俐芯? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,211評論 9 118
  • 第一次知道kotlin這個語言是在JakeWharton的這個dex-method-list 項目里棵介,本來這個項目...
    dodomix閱讀 13,378評論 4 15
  • 不重要的廢話 前段時間看了一遍《Programming Kotlin》,主要目的是想提高自己的英文閱讀能力泼各,能力提...
    珞澤珈群閱讀 3,362評論 1 7
  • 大家好鞍时,我是William李梓峰亏拉,歡迎加入我的Kotlin學習之旅扣蜻。今天是我學習 Kotlin 的第九天,學習內(nèi)容...
    William李梓峰閱讀 693評論 -3 0
  • 江南雨及塘,無邊夢莽使。細雨落在一片片蒼翠里,回聲響在一滴滴圓潤中笙僚。想去看看荷芳肌,看看夏雨...
    冰夫閱讀 112評論 0 0