写代码跟做饭其实有点像,食材处理不好,再厉害的火候也救不回来。在Android开发里,空指针就像厨房里的刀没放稳,一不小心就出事。Kotlin的空安全机制,就是帮你把刀挂到墙上,用的时候才拿下来。
可空类型:先声明,再动手
你不会直接往锅里倒未知的酱料,对吧?Kotlin也这样要求。如果一个变量可能为空,得明确标出来。比如字符串可能是空的,就得这么写:
var name: String? = null
加个问号,就像是贴了个标签:“这瓶调料可能空了,小心使用”。
安全调用操作符:稳妥下手
你想读取用户昵称的长度,但不确定有没有设置。这时候别硬来,用?.操作符,像用夹子取食材,安全又干净:
val length = user.name?.length
如果name是null,length就自动是null,不会崩溃。就像你发现酱油没了,就跳过调味步骤,不至于把锅烧穿。
Elvis操作符:备选方案要提前准备
做饭总有替代方案,代码也一样。当值可能为空时,用?:给个默认值:
val displayName = user.name ?: "匿名用户"
这就像你没买到香菜,就换上葱花,饭照样能吃。
非空断言:慎用!就像猛火快炒
有时候你100%确定某个值不会空,可以用!!强行调用。但这就像大火干烧锅底,风险自担:
val result = name!!.length
万一name其实是null,程序立马崩掉。这种操作最好只在测试或内部逻辑非常清楚时用,日常开发尽量避开。
let函数:安全包裹的烹饪步骤
需要对可能为空的对象执行多个操作?let帮你把逻辑包起来,只在非空时运行:
user.name?.let {
println("用户名是:$it")
saveToLog(it)
}
就像确认灶台有火才开始炒菜,避免做了一半才发现没开火。
初始化延迟变量:懒加载就像现煮米饭
有些变量不能一开始就赋值,但你又不想让它可空。用lateinit或by lazy,像是提前泡米,要用时再煮:
lateinit var database: DatabaseHelper
// 或
val config by lazy { loadConfig() }
只要确保在调用前完成初始化,就能避免空指针,还能提升启动速度。