Kotlin與Java:空安全

前言

空指針異常(NPE)是最為普遍與常見的異常舰攒,同時它也會引起諸如程序崩潰等非常嚴重的后果垂涯。為了避免出現(xiàn)NPE恼琼,常常需要開發(fā)者對變量進行判空處理炬太。特別是在Android中常常會使用‘鏈?zhǔn)健{(diào)用,但為了避免NPE隆敢,需要‘步步’判空,使得程序代碼啰嗦且難以維護崔慧。為解決此問題拂蝎,Kotlin提供了新的聲明,用于保證空安全惶室。

空安全

空安全簡單來說可在兩個階段進行:

  • 聲明時保證空安全
  • 使用時保證空安全

任何一個環(huán)節(jié)保證了空安全温自,則可避免空指針異常。

聲明時保證空安全

  • Java
    在Java中并不支持在聲明變量時就保證空安全皇钞,即不支持在編譯時就判斷變量是否可能為空悼泌。

  • Kotlin
    Kotlin提供了新的方式,用于聲明變量是否可能為空夹界。聲明的語法為:

變量名:變量類型馆里?

添加?的變量類型表示其對象可能為空可柿。若不添加表示其對象不可能為空鸠踪,在編譯時就可以提前發(fā)現(xiàn)該問題。

var a: String = "abc"
a = null // 編譯錯誤

var b: String? = "abc"
b = null // ok

在這一例子中复斥,變量a沒有聲明為可空類型营密,若對其賦值為空,則會編譯報錯目锭。但對于變量b聲明為可空類型后评汰,可以令其為空纷捞。

使用時保證空安全

  • Java
    在java中無法再聲明時就保證空安全,為此要避免NPE被去,必須在使用變量時保證空安全主儡。最基本也是最常見的手段就是:
if (b != null){
    //xxx
}
  • Kotlin
    在Kotlin中如果某個變量聲明為可空的類型,則在使用時也需要注意是否為空编振。Kotlin同樣支持像Java那樣顯式判空缀辩。同時也提供了安全調(diào)用符,即 踪央?.
val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length)

如果b不為空臀玄,就返回b.length,若b為空畅蹂,就返回null健无。該表達式的返回值類型為Int?

更為常見地,該調(diào)用符也可以支持’鏈?zhǔn)健{(diào)用:

bob?.department?.head?.name

若其中任何一個環(huán)節(jié)為空液斜,則返回空累贤。

安全調(diào)用也可以出現(xiàn)在賦值的左側(cè)。這樣少漆,如果調(diào)用鏈中的任何一個接收者為空都會跳過賦值臼膏,而右側(cè)的表達式根本不會求值:

person?.department?.head = managersPool.getManager()

空處理

  • Java
    當(dāng)我們有一個可空的引用 b 時,我們可以說“如果 b 非空示损,我使用它渗磅;否則使用某個非空的值 x”:
if (b != null){
    return b.length;
} else {
    return -1;
}
  • Kotlin
    要實現(xiàn)在變量為空時的處理,Kotlin不僅支持像Java那樣的顯式賦值检访,還擁有更為簡單的操作符始鱼,即Elvis 操作符 ?:
val l = b?.length ?: -1

如果 ?: 左側(cè)表達式非空,elvis 操作符就返回其左側(cè)表達式脆贵,否則返回右側(cè)表達式医清。 請注意,當(dāng)且僅當(dāng)左側(cè)為空時卖氨,才會對右側(cè)表達式求值会烙。

額外操作符

  • Kotlin
    在Kotlin中還支持一些Java不支持的新的操作符,如!!操作符双泪。
val l = b!!.length

如果該調(diào)用不為空持搜,則返回預(yù)期值,若為空焙矛,則拋出空指針異常葫盼。

安全類型轉(zhuǎn)換:如果對象不是目標(biāo)類型,那么常規(guī)類型轉(zhuǎn)換可能會導(dǎo)致 ClassCastException村斟。 另一個選擇是使用安全的類型轉(zhuǎn)換贫导,如果嘗試轉(zhuǎn)換不成功則返回 null:

val aInt: Int? = a as? Int
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抛猫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子孩灯,更是在濱河造成了極大的恐慌闺金,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峰档,死亡現(xiàn)場離奇詭異败匹,居然都是意外死亡,警方通過查閱死者的電腦和手機讥巡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門掀亩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欢顷,你說我怎么就攤上這事槽棍。” “怎么了抬驴?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵炼七,是天一觀的道長。 經(jīng)常有香客問我布持,道長豌拙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任题暖,我火速辦了婚禮姆蘸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芙委。我一直安慰自己,他們只是感情好狂秦,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布灌侣。 她就那樣靜靜地躺著,像睡著了一般裂问。 火紅的嫁衣襯著肌膚如雪侧啼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天堪簿,我揣著相機與錄音痊乾,去河邊找鬼。 笑死椭更,一個胖子當(dāng)著我的面吹牛哪审,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虑瀑,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼湿滓,長吁一口氣:“原來是場噩夢啊……” “哼滴须!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叽奥,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扔水,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后朝氓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魔市,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年赵哲,在試婚紗的時候發(fā)現(xiàn)自己被綠了待德。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡誓竿,死狀恐怖磅网,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筷屡,我是刑警寧澤涧偷,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站毙死,受9級特大地震影響燎潮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扼倘,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一确封、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧再菊,春花似錦爪喘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稠诲,卻和暖如春侦鹏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背臀叙。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工略水, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人劝萤。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓渊涝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子驶赏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

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