当类中存在很多全局实例变量实例时,为了保证它们能满足Kotlin的空指针检查语法标准,往往需要做许多的非空判断保护。为了解决这个问题,Kotlin允许对全局变量进行延迟初始化。
示例:
class MainActivity : AppCompatActivity, View.OnClickListener {
private lateinit var adapter: MyAdapter
override fun onCreate(savedInstanceState: Bunble?) {
...
adapter = MyAdapter();
}
override fun onClick(v: View?) {
...
adapter.notifyItemInserted(list.size() - 1)
}
}
在上诉代码中,在adapter变量前面加上了lateinit关键字,这样就可以在一开始的时候将它赋值为null了。
另外,还可以通过代码来判断一个全局变量是否已经完成了初始化,这样在某些时候才能够有效避免重复对某一个变量进行初始化操作。
示例:
class MainActivity : AppCompatActivity, View.OnClickListener {
private lateinit var adapter: MyAdapter
override fun onCreate(savedInstanceState: Bunble?) {
...
if (!::adapter.isInitialized) {
adapter = MyAdapter();
}
}
}
上诉代码中,::adapter.isInitialized可用于判断adapter变量是否已经初始化。
想象现在有这么一个Kotlin文件:
interface Result
class Success(val msg: String) : Result
class Failure(val error: Exception) : Result
再定义一个getResultMsg()方法,用于获取最终执行结果:
fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error.message
else -> throw Exception
}
在上诉代码中,我们不得不再编写一个else条件,否则编译器会报错。但实际上Result的执行结果只能是Success或者Failure,else在这里只是用来应付语法检查而已。
这个时候就可以使用密封类了,密封类的关键字是sealed class。
示例:
interface Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()
这个时候在getResultMsg()方法中的else条件已经不再需要了:
fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error.message
}
上诉代码中,当when语句中传入一个密封类变量作为条件时,Kotlin编译器会自动检查该密封类有哪些子类,并强制要求你将每一个子类所对应的条件全部处理。
注意:
本文整理自《第一行代码 Android》第三版,笔记文章,希望对大家有所帮助!