Kotlin 的空安全(Null Safety)并不是靠“运行时不断判空”实现的,而是在语言设计 + 编译器 + 运行时辅助三个层面共同完成的。下面从原理到实现逐步说明。
在 Kotlin 中:
var a: String // 不能为 null
var b: String? // 可以为 null
String 和 String? 是两种不同的类型String? 直接赋值给 Stringval x: String? = null
val y: String = x // ❌ 编译错误
这是 Kotlin 空安全的基础:用类型系统防止空引用
val s: String? = null
s.length // ❌ 编译错误
必须显式处理:
s?.length // 安全调用
s!!.length // 断言(可能抛 NPE)
if (s != null) s.length
fun foo(s: String?) {
if (s != null) {
s.length // 编译器自动转为 String
}
}
编译器在控制流分析中“知道”这里不可能为 null。
Java 没有空安全,Kotlin 用平台类型表示:
val s: String! = javaMethod() // 可能为 null,也可能不为 null
String! 是编译器内部类型Kotlin 并不是 100% 杜绝 NPE,而是通过减少发生概率 + 明确风险点。
!!val s: String? = null
s!!.length // NullPointerException
val list = javaList // 可能含 null
在 JVM 平台:
String 和 String? 编译后都是 java.lang.StringString a; // Kotlin: String
String b; // Kotlin: String?
区别在于:
编译器不允许你在错误的地方使用 b
| 语法 | 作用 |
|---|---|
? |
可空类型 |
?. |
安全调用 |
?: |
Elvis 运算符 |
!! |
非空断言 |
as? |
安全转型 |
let |
配合 ?. 使用 |
示例:
val len = s?.length ?: 0
Kotlin 的空安全,本质是把“是否可为 null”变成类型系统的一部分,由编译器在编译期强制检查,而不是靠运行时频繁判空。
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。