kotlin代碼中??!操作符的清楚方法
前言
空安全是Kotlin中非常實用的特性,它能夠讓你避免許多隱藏的NullPointerExceptions問題。然而當你使用AS將Java代碼轉換成Kotlin代碼后會出現(xiàn)很多的!! 操作符,因為出現(xiàn)!!意味著這里可能有未捕獲的KotlinNullPointerException異常。
對于一個有強迫癥的程序猿來說一個類中大篇幅的出現(xiàn)!! 絕對會使他們發(fā)瘋的。幸運的是我們可以通過以下方式避免使用!!操作符。
1. 使用val代替var
我們都知道val修飾的變量是只讀的,var修飾的變量是可變的,所以我們應該盡可能多的使用val,因為使用val修飾的變量必須有一個value,這樣你就不用再擔心空指針的問題,所以如果你能確定一個變量可以定義成一個常量,那么請用val修飾它。
2. 使用lateinit
然而你并不能把所有的變量用val修飾,,比如那些需要在Activity的onCreate()中進行初始換的變量,針對這個情況你可以考慮使用lateinit修飾變量,例如下面的代碼
private var mAdapter: RecyclerAdapter<Transaction>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun updateTransactions() {
mAdapter!!.notifyDataSetChanged()
}
把mAdapter使用lateinit修飾后代碼變成這樣
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun updateTransactions() {
mAdapter.notifyDataSetChanged()
}
需要注意的是如果訪問一個還沒有初始化的變量或屬性將會導致UninitializedPropertyAccessException異常。
還有一點需要注意的是lateinit并不能修飾基本數(shù)據(jù)類型的變量或屬性,比如Int,Boolean等等,它會提示你
‘lateinit'modifier is nor allowed on properites of primitive types
此時你可以使用下面這個方式
private var mNumber: Int by Delegates.notNull<Int>()
3. 使用let函數(shù)
下面這段代碼的提示我們經(jīng)常會見到

studio提醒我們mPhotoUrl的value在執(zhí)行uploadPhoto時可能已經(jīng)改變,不能確定是否非空,通常我們的解決方式是這樣的
private var mPhotoUrl: String? = null
fun uploadClicked() {
if (mPhotoUrl != null) {
uploadPhoto(mPhotoUrl!!)
}
}
然而如果你不想使用!! 這里還有一種更優(yōu)雅的方式
private var mPhotoUrl: String? = null
fun uploadClicked() {
mPhotoUrl?.let { uploadPhoto(it) }
}
只有當mPhotoUrl不為空時let中的代碼才會執(zhí)行
如果你對let函數(shù)還不了解,可以看我寫的這篇文章
//www.fzitv.net/article/131427.htm
4. 使用特定的函數(shù)處理復雜的場景
對于一些簡單的場景l(fā)et函數(shù)是很好用的,就像上面的情況,但是對于一些復雜的場景,比如下面的代碼
if (mUserName != null && mPhotoUrl != null) {
uploadPhoto(mUserName!!, mPhotoUrl!!)
}
當然你也可以使用let的方式處理,但是這樣代碼的可讀性就會降低了,這時候你可以定義一些特定的函數(shù)來解決這個問題。
比如下面這個可以判斷兩個參數(shù)非空的函數(shù)
fun <T1, T2> ifNotNull(value1: T1?, value2: T2?, bothNotNull: (T1, T2) -> (Unit)) {
if (value1 != null && value2 != null) {
bothNotNull(value1, value2)
}
}
這樣你的代碼就變成了下面這樣
ifNotNull(mUserName, mPhotoUrl) {
userName, photoUrl ->
uploadPhoto(userName, photoUrl)
}
See,!!操作符消失了。
5. 使用Elvis操作符
對于那些必有返回的情況,Elvis非常的實用。
Elvis操作符,?:左邊的返回值不為空則返回,否則返回?:右邊的值
fun getUserName(): String {
if (mUserName != null) {
return mUserName!!
} else {
return "Anonymous"
}
}
使用Elvis操作符后
fun getUserName(): String {
return mUserName ?: "Anonymous"
}
通過上面這幾種辦法基本上你可以清除程序中所有的!!操作符了,而且你的代碼也會變得更加健壯。如果你還有其他的方式請在評論區(qū)留言吧。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
android教程使用webview訪問https的url處理sslerror示例
這篇文章主要介紹了android教程使用webview訪問https的url處理sslerror示例,大家參考使用吧2014-01-01
Android Handler實現(xiàn)閃屏頁倒計時代碼
這篇文章主要介紹了Android Handler實現(xiàn)閃屏頁倒計時代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Android自定義ViewGroup實現(xiàn)標簽流容器FlowLayout
這篇文章主要介紹了Android自定義ViewGroup實現(xiàn)FlowLayout標簽流容器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
Android自定義RecyclerView Item頭部懸浮吸頂
這篇文章主要為大家詳細介紹了Android自定義RecyclerView Item頭部懸浮吸頂,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
基于Android10渲染Surface的創(chuàng)建過程
這篇文章主要介紹了基于Android10渲染Surface的創(chuàng)建過程,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08
Kotlin協(xié)程之Flow觸發(fā)與消費示例解析
Kotlin協(xié)程中,當需要消費流時,會調用collect方法,觸發(fā)流的消費,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2022-09-09
Android 使用Vitamio打造自己的萬能播放器(7)——在線播放(下載視頻)
本文主要介紹Android Vitamio開發(fā)播放器,這里提供在線播放和下載視頻實例代碼,有需要的小伙伴可以參考下2016-07-07

