对于 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