讓你的kotlin代碼遠離!!
對于 Null 的檢查是 Kotlin 的特點之一胳岂。強制你在編碼過程中考慮變量是否可為 null宏所,因此可以避免很多在 Java 中隱藏的 NullPointerException。
但是逛揩,當你用插件直接將 Java 代碼轉(zhuǎn)換為 Kotlin 時蹈集,你會發(fā)現(xiàn)有很多 !! 在里面。但其實 !! 意味著「有一個潛在未處理的 KotlinNullPointerException 在這里」茂缚。
這里就介紹 6 個避免 !! 的方法:
1. 用 val 而不是 var
在 Kotlin 中 val 代表只讀,var 代表可變屋谭。建議盡可能多的使用 val脚囊。val 是線程安全的,并且不需要擔(dān)心 null 的問題桐磁。只需要注意 val 在某些情況下也是可變的就行了悔耘。
2. 使用 lateinit
有些情況我們不能使用 val,比如我擂,在 Android 中某些屬性需要在 onCreate() 方法中初始化衬以。對于這種情況缓艳,Kotlin 提供了 lateinit 關(guān)鍵字。
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun test() {
mAdapter.notifyDataSetChanged()
}
要注意看峻,訪問未初始化的 lateinit 屬性會導(dǎo)致 UninitializedPropertyAccessException阶淘。
并且 lateinit 不支持基礎(chǔ)數(shù)據(jù)類型,比如 Int互妓。對于基礎(chǔ)數(shù)據(jù)類型溪窒,我們可以這樣:
private var mNumber: Int by Delegates.notNull()
3. 使用 let 函數(shù)
下面是 Kotlin 代碼常見的編譯錯誤:
許多開發(fā)者都會選擇 臨時應(yīng)急方法:
private var mPhotoUrl: String? = null
fun uploadClicked() {
mPhotoUrl?.let { uploadPhoto(it) }
}
但這里選擇 let 函數(shù)是一個更優(yōu)雅的解決方法:
private var mPhotoUrl: String? = null
fun uploadClicked() {
mPhotoUrl?.let { uploadPhoto(it) }
}
4. 創(chuàng)建全局函數(shù)來處理更復(fù)雜的情況
let 是一個對于 null 檢查很好的替代品,但有時我們會遇到更復(fù)雜的情況冯勉。比如:
if (mUserName != null && mPhotoUrl != null) {
uploadPhoto(mUserName!!, mPhotoUrl!!)
}
你可以選擇嵌套兩個 let澈蚌,但這樣可讀性并不好。這時你可以構(gòu)建一個全局函數(shù):
fun <T1, T2> ifNotNull(value1: T1?, value2: T2?, bothNotNull: (T1, T2) -> (Unit)) {
if (value1 != null && value2 != null) {
bothNotNull(value1, value2)
}
}
簡單調(diào)用 ifNotNull("", "", { a, b -> print("$a $b") })
- 使用 Elvis 運算符
Elvis 運算符在 Groovy 和 PHP 等語言中都存在灼狰。對于當值可能為 null 的情況特別方便:
fun getUserName(): String {
if (mUserName != null) {
return mUserName!!
} else {
return "Anonymous"
}
}
上面的代碼就可以簡化為:
fun getUserName(): String {
return mUserName ?: "Anonymous"
}
為什么叫 Elvis 呢宛瞄?因為 ?: 很像貓王的發(fā)型:
6. 自定義崩潰信息
如果我們使用 !!,那么當這個變量為 null 時交胚,只會簡單的拋出一個 KotlinNullPointerException
份汗。這時我們可以用 requireNotNull
或 checkNotNull
來附帶異常信息,方便我們調(diào)試承绸。
uploadPhoto(requireNotNull(intent.getStringExtra("PHOTO_URL"), { "Activity parameter 'PHOTO_URL' is missing" }))