0x1、要点提炼
- Kotlin中通过「非空类型」与「可空类型」来规避 NPE;
- 可空操作符「`?`」、安全调用操作符「`?.`」、非空断言运算符「`!!`」;
- Elvis操作符「`?:`」如果不为空返回它,否则返回另一个值;
- 安全的类型转换「`as?`」
- ?.let{}
- 不是绝对的空指针安全:Kotlin调用返回空的Java代码;
- Kotlin空安全的实现原理:
0x2、Kotlin里的空安全用法
NullPointerException(NPE),空指针异常,发生在运行时,引用一个空对象的方法时会抛出。
Java中常见的规避手段是:
在对象使用前进行判空:if (obj != null)
多层判空时显得不是很美观,而Kotlin中是「空安全」的:
编译期 就处理Null
空安全不是Kotlin特有的,其他很多编程语言也有,下面简述下Kotlin空安全的相关用法。
① 非空类型与可空类型
Kotlin中通过「非空类型」和「可空类型」来规避NPE,非空类型不能设置为Null值:
可空类型可以设置为Null值,在类型后加上 可空操作符(?) 即可,代码示例如下:
可空类型,直接访问它的属性或方法,会报错:
可以通过 安全调用操作符(?.) 或 非空断言运算符(!!) 来解决,代码示例如下:
运行结果如下:
② Elvis操作符(?:)
三目条件运算符的简略写法:如果不是空,就返回它,否则返回另一个值。代码示例如下:
③ 安全的类型转换
Kotlin中可以使用as
关键字来进行类型转换,而使用as?
表示安全类型的转换。最常见的使用场合,后台接口返回一个参数,需要我们自己做下类型转换,直接用as的话,如果参数为null或者非String类型,就可能引发异常,如果用as? ,参数异常则不会转换,代码示例如下:
运行结果如下:
④ ?.let{}
let函数除了可用于在同一个作用域下操作变量外(代码更优雅)外:
tvTitle.let { it.text = "标题" it.textSize = 18.0f it.gravity = Gravity.LEFT or Gravity.CENTER it.setOnClickListener {} }
还可以用作做判null操作,比如下面这样的代码:
test我们已经设置了一个值,但是还是报错,添加上一个非空断言即可:
还有个更优雅的写代码方式,就是用2,修改后的代码如下:
另外?.let{}遍历集合会忽略null值,只对非null值执行操作;除此之外,还可以用集合操作函数filterNotNull过滤出非空元素。