用可空类型提前预防空指针
在日常开发中,空指针异常是最常见的崩溃来源之一。比如处理用户提交的表单数据时,某个字段可能为空。Kotlin 的可空类型设计从语法层面帮我们规避这类问题。声明变量时加上 ?,就明确告诉编译器这个值可能是 null。
var username: String? = null // 可为空
var age: Int? = null这样一来,如果直接调用 username.length,编译器就会报错,逼你先做判空处理,相当于在写代码时就被提醒“这里可能出事”。
安全调用操作符:?. 让调用不再冒险
还是上面的用户名场景,想获取它的长度但又不确定是否为空,用 ?. 就能安全操作。
val length = username?.length如果 username 是 null,length 就是 null,不会崩溃。这种写法特别适合处理网络接口返回的数据,比如用户头像 URL 可能不存在,用 safe call 能平滑处理。
Elvis 操作符 ?: 提供默认值
很多时候我们希望空值时有个兜底方案。比如显示用户名,如果没有就展示“游客”。这时 Elvis 操作符就很顺手。
val displayName = username ?: "游客"结合安全调用还能链式处理:
val firstChar = username?.get(0) ?: '未'这样既安全又简洁,避免写一堆 if-else 判断。
非空断言 !!. 谨慎使用
有些时候你非常确定某个值不会为空,比如初始化已完成的对象,可以用 !!. 强行调用。
username!!.toUpperCase()但这就像开车不系安全带——能跑得快,出事也快。一旦值确实是 null,程序立马抛出异常。建议只在测试或内部逻辑非常清晰的场景下使用。
let 函数配合安全调用
当需要对一个可空对象执行多个操作时,let 配合 ?. 能让代码更清晰。
username?.let { name ->
println("用户名是:$name")
println("长度为:${name.length}")
}只有 username 不为空时,块内的代码才会执行,避免了重复判空。
函数参数和返回值的空安全设计
定义函数时,明确参数是否可空,能让调用者更清楚使用规范。比如解析手机号的函数:
fun formatPhone(phone: String?): String {
return phone?.trim()?.takeIf { it.isNotEmpty() } ?: "未知号码"
}输入可空,输出不可空,接口语义清晰。别人调用时也不用担心返回 null 导致下游出问题。
实际办公场景中的应用
在公司内部系统里,经常要处理员工信息表格导入。Excel 中某些列可能为空,比如“部门编号”。用 Kotlin 处理时,字段直接定义为 String?,再配合安全调用和默认值,解析过程几乎不会因数据异常而中断。
以前常因为一条脏数据导致整个导入失败,现在最多是某条记录标记为“部门缺失”,其他正常入库,运维压力小了很多。