kotlin-Null safety
原文
我翻译的一篇文章。
概览
在本篇文章,我们将要研究一下 Kotlin 语言内置的 null 安全特性。 Kotlin 提供了可推测的,本地处理的可空字段 - 不需要额外的支持库。
Maven 依赖
<dependency> |
空值和非空值引用类型
Kotlin 有两种可以被编译器解释的引用类型,能够在编译阶段告知程序员代码的正确性 - 空值和非空值
默认情况下, Kotlin认为都是非空值:
var a: String = "value" |
我们不能把 null 赋值给 a, 如果你尝试赋值,编译器会报错。
如果我们想创建一个可以赋空值的变量时,需要在定义变量的时候在后面添加一个 ?
var b: String? = "value" |
这时就可以合法的赋空值了
b = null |
当我们想要访问 b 的时候,我们必须处理 null 的情况来避免编译错误,因为 Kotlin 知道这个变量可能为空
if (b != null) { |
Elvis操作符
有时,我们希望操作空值时能返回指定的默认值。 这时可以使用 elvis(?:) 操作符,对于 Java Optional class 来说相当于 orElse/orElseGet
val value: String? = null |
当引用值非空时, length 方法会被调用
val value: String? = "name" |
!! 操作符 强制转换
可以使用 !! 来人工保证不会是空值
val nullableInt: Int? = 1 |
Safe Calls ?.
处理每个空值非常繁琐。幸运的是 Kotlin 提供了一个语法称为 “safe calls”,这个语法运行程序员只有在指定引用不为空值的时候执行动作。
下面定义两个数据类,演示一下这个特性:
data class Person(val country: Country?) |
我们可以看到 country 和 code 字段都是可以为空的类型
访问这些字段的时候,我们可以使用 safe call 语法:
val p: Person? = Person(Country("ENG")) |
当 p 为空值的时候,safe call 语法返回 null
val p: Person? = Person(Country(null)) |
let()方法
只想在一个引用不是空值的时候执行动作,我们可以使用 let 操作符。
这里有一个值得列表,里面有空值
val firstName = "Tom" |
然后,我们可以使用 let 函数在列表里面的每个非空值上执行操作
var res = listOf<String?>() |
also() 方法
如果我们想要做一些额外的操作,例如:在操作每个非空值的时候记录日志,我们可以使用 also() 方法,连接在 let()后面
var res = listOf<String?>() |
这样就可以打印出每个非空值的信息
non nullable value: Tom |
run()方法
Kotlin 有一个 run() 方法用来在空值引用上执行一些操作。他和 let() 很像,但是是在函数体内,run() 方法操作这个引用,代替函数参数。
var res = listOf<String?>() |
Nullable Unsafe Get
Kotlin也提供了一个不安全的操作符,可以跳过空值检查逻辑来获取可以为空值的字段,但是要小心使用。
两个 “!!” 可以从一个空值引用中获取数值并且在为空时抛出 NullPointerException 异常。这个和 Optional.get() 操作是等价的。
var b: String? = "value" |
如果这个空值引用的值非空,那么操作可以成功执行。
val b: String? = "value" |
从列表中过滤空值
Kotlin 的 List 类有一个工具方法 filterNotNull() 只返回列表中的非空数值。
val list: List<String?> = listOf("a", null, "b") |
这是一个非常有用的想法,封装了常用的操作逻辑,不用我们自己来实现。
结论
在这里,我们深入探讨了 Kotlin 的空值安全特性。我们看到了两种类型,空值和非空值。我们使用 safe call 和 elvis 操作符实现了优雅的处理空值逻辑
样例和代码在GitHub,是一个Maven项目