空安全(?、?.、!!、?:)
1. 空安全的概念
Kotlin 通过**空安全(Null Safety)**机制,在编译时检测潜在的 NullPointerException(NPE),从而减少运行时崩溃的风险。与 Java 不同,Kotlin 默认所有变量不可为 null,除非显式声明为可空类型。
2. 可空类型与操作符
2.1 可空类型声明
在变量类型后添加 ?,表示该变量可以存储 null:
var name: String? = null // 可空字符串
2.2 安全调用操作符 ?.
如果对象不为 null,则调用其方法或属性;否则返回 null:
val length: Int? = name?.length // 若 name 为 null,则 length 为 null
2.3 非空断言操作符 !!
强制调用可空对象的方法或属性,若对象为 null 则抛出 NPE:
val length: Int = name!!.length // 若 name 为 null,抛出异常
2.4 Elvis 操作符 ?:
提供默认值,当左侧表达式为 null 时返回右侧值:
val length: Int = name?.length ?: 0 // 若 name 为 null,返回 0
3. 实际应用场景
3.1 链式安全调用
val city: String? = user?.address?.city // 避免多层嵌套 null 检查
3.2 结合 let 处理非空值
name?.let {
println(it.uppercase()) // 仅在 name 非空时执行
}
3.3 平台类型(与 Java 互操作)
Java 代码返回的变量可能为 null,Kotlin 会标记为平台类型(如 String!),需显式处理:
val javaValue: String! = JavaClass.getNullableString()
val safeValue: String = javaValue ?: "default"
4. 最佳实践
- 优先使用安全调用(
?.):避免直接使用!!。 - 合理使用 Elvis 操作符:为可空变量提供默认值。
- 避免过度嵌套:结合
let或 Elvis 操作符简化代码。
5. 示例代码
fun printNameLength(name: String?) {
val length = name?.length ?: "unknown".length
println("Length: $length")
}
fun main() {
printNameLength("Kotlin") // 输出: Length: 6
printNameLength(null) // 输出: Length: 7
}
注意:空安全是 Kotlin 的核心特性之一,合理利用可显著提升代码健壮性。
