android开发(kotlin) 延迟初始化和密封类
本文介绍了Kotlin中的两个实用特性:延迟初始化和密封类。延迟初始化通过lateinit关键字避免了全局变量的空类型声明和频繁判空问题,同时可用::var.isInitialized检查初始化状态。密封类使用sealed class强制处理所有子类条件分支,优化when表达式逻辑,要求密封类及其子类必须定义在同一文件的顶层位置。这两个特性分别解决了变量初始化和多态类型检查的问题,提高了代码的安全
变量的延迟初始化
class AbcActivity : ComponentActivity() {
private var person: Person? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_abc)
person = Person(30);
}
fun doWork() {
val a = person?.age
}
}
将person设置成全局变量,Person的初始化在oncreate()中,所以person赋值为null,需要把类型声明Person?。
在doWork()中,person调用任何方法都要进行判空处理。
当全局变量越来越多,可能需要编写大量的判空处理代码。解决这个问题需要使用延迟初始化,延迟初始化使用lateinit关键字。
class AbcActivity : ComponentActivity() {
private lateinit var person: Person
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_abc)
person = Person(30);
}
fun doWork() {
val a = person.age
}
}
判断全局变量是否完成了初始化。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_abc)
if (!::person.isInitialized) {
person = Person(30)
}
}
::person.isInitialized可用于判断变量是否已经初始化。
使用密封类优化代码
创建Result.kt文件
interface Result
class Success(val msg: String) : Result
class Failure(val error: Exception) : Result
编写getResultMsg()函数,处理result
fun getResultMsg(result: Result) = when(result){
is Success ->result.msg
is Failure -> result.error.message
else -> throw IllegalArgumentException()
}
使用上面的代码,必须实现else条件,编译器会认为这里缺少条件分支。其实只有两种情况Success和Failure。
另外,如果新增class并实现Result接口,没有在getResultMsg()添加相应的条件分支,在运行时会进入else条件里面。
kotlin使用sealed class处理了这个问题,将Result接口改成密封类。
sealed class Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()
去掉else,没有报错
fun getResultMsg(result: Result) = when(result){
is Success ->result.msg
is Failure -> result.error.message
}
没有报错的原因是,当在when语句中传入一个密封类变量作为条件时,Kotlin编译器会自动检查改密封类有哪些子类,并强制要求你将每一个子类所对应的条件全部处理。不会出现漏写条件分支的情况。在Result.kt中新增一个Un类。
sealed class Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()
class Un(val error: Exception) : Result()
getResultMsg()方法会报错,要求处理新的分支问题。
密封类及其子类只能定义在同一个文件的顶层位置,不能嵌套在其他类中。
更多推荐
所有评论(0)