對於 Null 的檢查是 Kotlin 的特色之一。強制你在編碼過程當中考慮變量是否可爲 null,所以能夠避免不少在 Java 中隱藏的 NullPointerException。android
可是,當你用插件直接將 Java 代碼轉換爲 Kotlin 時,你會發現有不少 !! 在裏面。但其實 !! 意味着「有一個潛在未處理的 KotlinNullPointerException 在這裏」。安全
這裏就介紹 6 個避免 !! 的方法:ide
在 Kotlin 中 val 表明只讀,var 表明可變。建議儘量多的使用 val。val 是線程安全的,而且不須要擔憂 null 的問題。只須要注意 val 在某些狀況下也是可變的就好了。函數
能夠看看這裏:Mutable vals in Kotlin
有些狀況咱們不能使用 val,好比,在 Android 中某些屬性須要在 onCreate() 方法中初始化。對於這種狀況,Kotlin 提供了 lateinit 關鍵字。ui
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mAdapter = RecyclerAdapter(R.layout.item_transaction) } fun updateTransactions() { mAdapter.notifyDataSetChanged() }
要注意,訪問未初始化的 lateinit 屬性會致使 UninitializedPropertyAccessException。編碼
而且 lateinit 不支持基礎數據類型,好比 Int。對於基礎數據類型,咱們能夠這樣:spa
private var mNumber: Int by Delegates.notNull<Int>()
下面是 Kotlin 代碼常見的編譯錯誤:.net
許多開發者都會選擇 quick-fix:插件
private var mPhotoUrl: String? = null fun uploadClicked() { if (mPhotoUrl != null) { uploadPhoto(mPhotoUrl!!) } }
但這裏選擇 let 函數是一個更優雅的解決方法:線程
private var mPhotoUrl: String? = null fun uploadClicked() { mPhotoUrl?.let { uploadPhoto(it) } }
let 是一個對於 null 檢查很好的替代品,但有時咱們會遇到更復雜的狀況。好比:
if (mUserName != null && mPhotoUrl != null) { uploadPhoto(mUserName!!, mPhotoUrl!!) }
你能夠選擇嵌套兩個 let,但這樣可讀性並很差。這時你能夠構建一個全局函數:
fun <T1, T2> ifNotNull(value1: T1?, value2: T2?, bothNotNull: (T1, T2) -> (Unit)) { if (value1 != null && value2 != null) { bothNotNull(value1, value2) } }
Elvis 運算符在 Groovy 和 PHP 等語言中都存在。對於當值可能爲 null 的狀況特別方便:
fun getUserName(): String { if (mUserName != null) { return mUserName!! } else { return "Anonymous" } }
上面的代碼就能夠簡化爲:
fun getUserName(): String { return mUserName ?: "Anonymous" }
爲何叫 Elvis 呢?由於 ?: 很像貓王的髮型:
![]()
若是咱們使用 !!,那麼當這個變量爲 null 時,只會簡單的拋出一個 KotlinNullPointerException。這時咱們能夠用 requireNotNull 或 checkNotNull 來附帶異常信息,方便咱們調試。
uploadPhoto(requireNotNull(intent.getStringExtra("PHOTO_URL"), { "Activity parameter 'PHOTO_URL' is missing" }))
總而言之,絕大多數狀況下你都不須要 !!,能夠用上面提到的 6 個技巧來消除 !!。這樣能讓代碼更安全、更容易 debug 而且更乾淨。
原文:How to remove all !! from your Kotlin code