首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kotlin 空安全最佳实践

1

前言

Kotlin语言在设计时,重点关注了 的空指针异常(NullPointerException,简称NPE),然而在使用时,由于 NPE 出现的原因及其多样化,不仅仅是 Kotlin 内部的,更有 Kotlin 和 Java 互相调用时的 NPE ,对应的处理方式也有很多种,很多时候单靠一个不能优雅地解决所有问题,在不同场合,我们可以通过不同的方式,来简化书写,明确语义。

2

Kotlin 产生 NPE 的原因

官网文档中,列出了以下几种NPE产生原因:

1.在代码中,显式地调用了 ;

2.使用了 操作符;

!!,非空断言运算符,作用是将任何值转换为非空类型,若该值为空,则会抛出NPE,例如:

3.有些数据在初始化时不一致,例如:

(1) 传递一个在构造函数中出现的未初始化的this并用于其他地方(“泄漏this”);

在构造方法中传入了 this ,但是 this 可能没有初始化完全(比如部分成员未初始化),可能造成 NPE

(2) 超类的构造函数调用一个开放成员,该成员在派生中类的实现使用了未初始化的状态;

此处 的属性 引用,会抛出 NPE ,原因在于超类 的构造方法中调用了子类的方法,而此时子类中 尚未初始化,此时会NPE。

4.Java 互操作:

(1) 企图访问平台类型的引用的成员

Java 中所有的类型都是可空的,在 Kotlin 中,Java 声明的类型会在编译期间映射成相应非空的 Kotlin 类型,比如对应 Kotlin 中的,这时,可能由于在 Kotlin 中引用了可能为空的 Java String 类型,导致 NPE :

item可能为空,因为 获取的是一个对象,而 Java 对象都是可空的。故而在使用诸如时,可能会抛出 NPE

(2) 用于具有错误可空性的 Java 互操作的泛型类型

例如一段 Java 代码可能会向 Kotlin 的 中加入 ,这意味着应该使用 来处理它:

上面 类里面定义了一个非空的 类型的 mStudent ,所以在 方法企图添加null到集合时,编译直接报错,但是在 Java中却可以:

(3) 由外部 Java 代码引发的其他问题

上述代码中,在 里,有一个 方法返回了 ,在 类 中引用,编译通过,但是运行时会抛出异常:

3

空检查 ( null check ) 的应用场景

在实际的应用开发中,我们可能遇到很多情况需要面临对 NPE 的处理,例如对值的、对对象的、对类型的、对方法的…等,在诸多场景中,我们可以根据关注处理点的不同,将场景分为下面几种:

1.只关注非空场景,不需要处理为空的场景

(1) 使用 声明可空类型,避免抛出 NPE

如果变量可能为空,则在定义时一定要使用 标示,当为空时,程序不会往下执行,也不会抛出 NPE

(2) 使用 非空断言运算符 声明非空类型,为空则抛出 NPE

更改 (1) 中代码,将 student 从改为修饰,则 student 为空时会抛出NPE。当程序需要显示抛出 NPE 时,则可以使用来将类型强转成非空的类型

(3) 使用 标注代码块

let的使用场景是很多的,特别是对于对象的处理,将大量的对象处理的代码块放到非空的 中,可以保证里面所有对对象使用的代码都是空安全的。

2.非空和不非空,都需要处理的场景

(1) 使用 Elvis 操作符

当为空时,输出的是 后面的默认字符串。 Elvis 不仅仅可以返回为空时的默认值,还可以抛出异常或者返回异常时的处理函数

Elvis 操作符跟 Java 中的 很像,但是意义略有不同, Elvis 是 Java 在判空时的简写,例如, 在 Java 中相当于:

(2) 使用

Kotlin 中,if else 是表达式,是有返回值的,所以不仅能做空判断,还能作为返回值

(3) 使用类型判断 来判断是否为空,如果符合 条件,则 student 不为空

(4) 也可以通过 来判断是否为空

4

总结

Kotlin是基于 JVM 的语言,在设计时,既要 100% 兼容 Java,又要规避 Java 中的空指针异常,所以对于空指针异常的处理是多样化的。我们在使用时不仅要知道如何去规避或处理空指针异常,还要力求优雅,在不同的场合使用最合适的方式。

5

引用资料

官网: https://kotlinlang.org/docs/reference/null-safety.html

空指针异常: https://medium.com/keepsafe-engineering/an-in-depth-look-at-kotlins-initializers-a0420fcbf546

kotlin 空安全: https://stackoverflow.com/questions/34498562/in-kotlin-what-is-the-idiomatic-way-to-deal-with-nullable-values-referencing-o

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180720G0K6F500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券