日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kotlin中?和!!的区别

發(fā)布時間:2025/3/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kotlin中?和!!的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

很多同學剛上手使用Kotlin知道它有針對Java NullPointerException的管理,而在Kotlin中?和!!均是和NullPointerException有關系,可他們的區(qū)別到底是什么呢?為什么別人開發(fā)的項目中出現(xiàn)了好多"?",而我讀起來卻滿臉問號。


不懂就問百度呀,確實有人解釋它們的區(qū)別,比如:

這是輸入"kotlin ?和!!"搜索到的百度第一條答案,確實這位說的沒錯。不過我覺得對于一個剛接觸KT(Kotlin)的新手來說,他恐怕需要有漢語八級才能透徹理解這兩句話的意思。

先闡述兩個概念:
"?"加在變量名后,系統(tǒng)在任何情況不會報它的空指針異常。
"!!"加在變量名后,如果對象為null,那么系統(tǒng)一定會報異常!

?

先拿Java代碼舉個例子

ArrayList<String> myList = null; // 創(chuàng)建一個null的隊列Log.d("TAG", "-->> List Size = " + myList.size());

這個例子中,執(zhí)行到Log打印隊列長度時,大家都知道系統(tǒng)一定會報NullPointerException。然而如果在KT中,在調用myList的時候在它后面加上一個問號myList?.size(),當myList為null的時候直接會打印List Size = null并不會有null異常出現(xiàn)。

當使用Android Studio把上面那段Java自動轉換成KT代碼寫法后:

val myList : ArrayList<String>? = nullLog.d("TAG", "-->> List Size = ${myList!!.size}")

編譯器為什么自動把myList.size()變成了myList!!.size呢,為什么加上的是感嘆號不是問號。

這是因為編譯器在轉化時為了保證代碼轉化前后的一致性所造成的。換句話說,在Java上出異常的,轉化到KT上,編譯器任然會讓他保持拋出異常,NullPointerException也是如此。

所以結合上下文可以看得出,!!加上去后好像并沒有和之前Java代碼有什么區(qū)別嘛,該null的地方任然會拋出異常。所以大多數(shù)情況下都會使用?來檢測null,輪不到!!出場。!!只會在你需要對某對象進行非空判斷,并且需要拋出異常時才會使用到。

那我們接下來著重講解一下?到底怎么用。
在聲明對象時,把它跟在類名后面,表示這個類允許為null;
在調用對象時,把它跟在對象后面,表示如果為null程序就會視而不見。
如下列代碼:

// 這是聲明一個變量,問號跟在類名后面var room: Room? = Room()private fun checkRoom() { // 因為加上了問號,所以可以任意的把room變成空 room = null // 因為在調用時加上了問號,所以程序不會拋出異常 Log.d("TAG", "-->> room name = ${room?.roomName}") }

再舉個不用?的例子:

// 這樣程序就默認的給room加上了!!,從此以后room不允許為nullvar room: Room = Room()private fun checkRoom() { // 當把null賦給room時,從編譯的時候就已經(jīng)不通過 room = null // 并且編譯器建議把對象后面的問號刪除,因為這個對象永遠不為空 Log.d("TAG", "-->> room name = ${room.roomName}") }

所以加上?是一種安全的寫法,它體現(xiàn)了Kotlin null safety的特性。
KT的語法很靈動,定義參數(shù)還可以寫成

val room: Room? = Room() // 先實例化一個room,并且room可以為空val room: Room? = null // 不實例化了,開始room就是空的val room: Room = Room() // 實例化一個room,并且room永遠不能為空 val room = Room() // 和上一行代碼一樣,是KT最常用的簡寫語法



然而加上問號以后程序就萬事大吉永遠擺脫了NullPointerException的煩惱?我們再看下一段代碼:

val roomList: ArrayList<Room>? = nullif (roomList?.size > 0) { Log.d("TAG", "-->> 房間數(shù)不是0") }

當我們判斷l(xiāng)ist.size的時候,編譯器會告訴我們"Operator call corresponds to a dot-qualified call 'roomList?.size.compareTo(0)' which is not allowed on a nullable receiver 'roomList?.size'."。大概意思是,當roomList為null的時,它的size返回就是"null",但是"null"不可以和int值比大小,所以編譯器建議我們寫成roomList?.size!! > 0。

沒錯,經(jīng)過編譯器的建議加上了!!,我們程序運行到這行代碼,roomList為null時它一定會報異常。所以是不是必須得在外面套一層if(roomList != null)這種Java常見語句才能避免異常嗎?

當然Kotlin不會讓程序出現(xiàn)這種啰嗦的代碼,所以里面提供了對象A ?: 對象B表達式,并且取消了Java中的條件表達式 ? 表達式1 : 表達式2這個三元表達式。

?:表示的意思是,當對象A值為null的時候,那么它就會返回后面的對象B。

val roomList: ArrayList<Room>? = nullval mySize= roomList?.size ?: 0

此時mySize的值就為0,因為roomList?.size為空。

所以我們可以把上面的代碼改成這樣:

val roomList: ArrayList<Room>? = nullif (roomList?.size ?: 0 > 0) { // 這一行添加了?: Log.d("TAG", "-->> 房間數(shù)不是0") }

就目前為止使,用上面的??:基本上能避免程序中出現(xiàn)的所有NullPointerException。



作者:Jason_Samuel
鏈接:https://www.jianshu.com/p/51b2e5aa3dd8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯(lián)系作者獲得授權并注明出處。

轉載于:https://www.cnblogs.com/weizhxa/p/9982536.html

總結

以上是生活随笔為你收集整理的Kotlin中?和!!的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。