学习Kotlin之延迟初始化和密封类
对变量延迟初始化
如果你的类中存在很多全局变量实例,为了保证它们能够满足Kotlin的空指针检查语法标准,你不得不做许多的非空判断保护才行。
解决办法就是对全局变量进行延迟初始化,使用的是lateinit关键字。意思是晚点对这个变量进行初始化,这样就不用一开始赋值为null了, 同时需要声明类型。
private lateinit var adapter: FruitAdapter
另外,我们可以判断一个全局变量是否已经完成了初始化,避免重复对某一个变量进行初始化操作:

具体语法就是这样,::adapter.isInitialized可用于判断adapter变量是否已经初始化。然后我们再对结果进行取反,如果还没有初始化,那么就立即对adapter变量进行初始化。
使用密封类优化代码
密封类通常可以结合RecyclerView适配器中的ViewHolder一起使用。它可以在很多时候帮助你写出更加规范和安全的代码。
了解一下密封类具体的作用
新建一个Kotlin文件,文件名叫Result.kt。

这里定义了一个Result接口,用于表示某个操作的执行结果,接口中不用编写任何内容。
然后定义了两个类去实现Result接口:一个Success类用于表示成功时的结果,一个Failure类用于表示失败时的结果,这样就把准备工作做好了。
接下来再定义一个getResultMsg()方法,用于获取最终执行结果的信息:

实际上Result的执行结果只可能是Success或者Failure,这个else条件是永远走不到的,但是不得不写,否则无法编译通过。
其次,如果新增了一个Unknown类并实现Result接口,用于表示未知的执行结果,但是忘记在getResultMsg()方法中添加相应的条件分支,编译器不会提醒,会在运行的时候进入else条件里面,从而抛出异常并导致程序崩溃。
Kotlin的密封类
Kotlin的密封类可以很好地解决这个问题,关键字是sealed class。

将interface关键字改成了sealed class。另外,由于密封类是一个可继承的类,因此在继承它的时候需要在加上一对括号。
这个时候就不要else条件了。

而如果我们现在新增一个Unknown类,并也让它继承自Result,此时getResultMsg()方法就一定会报错,必须增加一个Unknown的条件分支才能让代码编译通过。
注意:密封类及其所有子类只能定义在同一个文件的顶层位置,不能嵌套在其他类中。

浙公网安备 33010602011771号