Kotlin學習 3 -- 延遲初始化和密封類

本篇文章主要介紹以下幾個知識點:

SUMMER DAY (圖片來源于網(wǎng)絡)

1. 對變量延遲初始化:關鍵字 lateinit

Kotlin 語言的許多特性,如變量不可變,變量不可為空等都是為了盡可能保證程序安全而設定的,但有些時候這些特性在編碼時卻會帶來不少麻煩。

當你的類中存在很多全局變量實例听皿,為了滿足空指針檢查語法標準,不得不做很多的非空判斷,即使確定它們不會為空刊橘。

以項目中常見的 adapter 為例,在 activity 中的偽代碼如下:

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private var adapter: MyAdapter? = null // 把 adapter 設為全局變量
    
    override fun onCreate(savedInstanceState: Bundle?) {
        adapter = MyAdapter(mList) // 初始化 adapter
    }

    override fun onClick(v: View?) {
        adapter?.notifyItemInserted(mList.size - 1) // 點擊調(diào)用 adapter 的方法
    }
}

上述代碼中颂鸿,把 adapter 設置為全局變量促绵,在 onCreate() 中初始化,從而不得不先將 adapter 賦值為 null嘴纺, 并把它類型聲明為 MyAdapter?败晴,當調(diào)用 adapter 方法時還需進行判空處理(即使已經(jīng)初始化過了)。

代碼中有大量的全局變量時栽渴,就得編寫大量額外的判空處理尖坤,這時候就可以考慮對全局變量進行延遲初始化。

延遲初始化用的是 lateinit 關鍵字闲擦,它相當于告訴 Kotlin 編譯器會在晚些時候?qū)@個變量進行初始化慢味,這樣一開始就不用對它賦值 null 了场梆。

lateinit,上述代碼可改為:

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var adapter: MyAdapter // 延遲初始化 adapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        adapter = MyAdapter(mList) // 初始化 adapter
    }

    override fun onClick(v: View?) {
        adapter.notifyItemInserted(mList.size - 1) // 點擊調(diào)用 adapter 的方法纯路,此時無需做判空處理
    }
}

當然或油,在用了 lateinit 關鍵字后,若變量還沒初始化的情況下就使用它感昼,則會拋出 UninitializedPropertyAccessException 異常装哆。

另外,還可以通過 isInitialized 來判斷一個全局變量是否已經(jīng)完成了初始化定嗓,這樣也能在某些時候避免重復對某個變量初始化操作:

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var adapter: MyAdapter // 延遲初始化 adapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // ::adapter.isInitialized 判斷 adapter 變量是否已經(jīng)初始化
        if(!::adapter.isInitialized){
           adapter = MyAdapter(mList) // 沒有初始化則初始化 adapter
        }
    }
}

2. 使用密封類優(yōu)化代碼:關鍵字 sealed class

首先來看一個例子蜕琴,這里定義一個 Result 接口,再分別定義成功類和失敗類去實現(xiàn)這個接口:

interface Result
class Success(val msg: String) : Result
class Failure(val error: Exception) : Result

接下來在定義一個方法用于獲取結(jié)果的信息:

fun getResultMsg(result: Result) = when (result) {
    is Success -> result.msg
    is Failure -> result.error.message
    else -> throw IllegalArgumentException()
}

上述代碼存在的問題:

  1. 雖然只有兩種情況宵溅,但還是不得不再編寫個 else 條件來判斷凌简,否則編譯不通過。

  2. 倘若新增了一個 Unknow 類并實現(xiàn) Result 接口恃逻,但沒在 getResultMsg() 方法中添加相應的條件判斷雏搂,編譯器不會提醒,而是會走 else 條件語句寇损,從而拋出異常凸郑。

這時候就可以考慮用使用密封類優(yōu)化代碼。

密封類的關鍵字是 sealed class矛市,當在 when 語句中傳入一個密封類變量作為條件時芙沥,編譯器會自動檢查該密封類有哪些子類,并強制要求將每一個子類對應的條件全部處理浊吏。

sealed class而昨,上述代碼可改為:

sealed class Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()

此時,getResultMsg() 方法中就無需編寫 else 條件了:

fun getResultMsg(result: Result) = when (result) {
    is Success -> result.msg
    is Failure -> result.error.message
}

注:密封類及其所有子類只能定義在同一個文件的頂層位置找田,不能嵌套在其他類中歌憨,這是被密封類底層的實現(xiàn)機制所限制的。

小結(jié):密封類可以使代碼更加嚴謹墩衙。

本篇文章就介紹到這务嫡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漆改,隨后出現(xiàn)的幾起案子植袍,更是在濱河造成了極大的恐慌,老刑警劉巖籽懦,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件于个,死亡現(xiàn)場離奇詭異,居然都是意外死亡暮顺,警方通過查閱死者的電腦和手機厅篓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門秀存,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人羽氮,你說我怎么就攤上這事或链。” “怎么了档押?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵澳盐,是天一觀的道長。 經(jīng)常有香客問我令宿,道長叼耙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任粒没,我火速辦了婚禮筛婉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘癞松。我一直安慰自己爽撒,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布响蓉。 她就那樣靜靜地躺著硕勿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪枫甲。 梳的紋絲不亂的頭發(fā)上源武,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音言秸,去河邊找鬼软能。 笑死迎捺,一個胖子當著我的面吹牛举畸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凳枝,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼抄沮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岖瑰?” 一聲冷哼從身側(cè)響起叛买,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹋订,沒想到半個月后率挣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡露戒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年椒功,在試婚紗的時候發(fā)現(xiàn)自己被綠了捶箱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡动漾,死狀恐怖丁屎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旱眯,我是刑警寧澤晨川,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站删豺,受9級特大地震影響共虑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吼鳞,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一看蚜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赔桌,春花似錦供炎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雪位,卻和暖如春竭钝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雹洗。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工香罐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人时肿。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓庇茫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親螃成。 傳聞我的和親對象是個殘疾皇子旦签,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348