这是我参与「第四届青训营 」笔记创作活动的第5天
空指针异常处理
空指针异常(NullPointerException)是开发中经常遇到的一种异常。
下面是一个 Java 的方法
public void doStudy(Study study) {
study.readBooks();
study.doHomework();
}
上面的代码就存在空指针异常问题,如果向该方法传入了一个 null 参数,那么在调用方法时就会抛出空指针异常。因此,更加稳妥的做法是在调用参数的方法之前先进行判空处理,比如:
public void doStudy(Study study) {
if (study != null) {
study.readBooks();
study.doHomework();
}
}
这样就能保证不管传入的参数是什么,这段代码始终都是安全的。
Kotlin 利用编译时判空检查的机制几乎杜绝了空指针异常。
比如向 Kotlin 的函数中传入 null ,IDE 会直接报错。
如果希望能够向该函数中传 null ,可以在类型后面用 ? 表明
fun doStudy(study: Study?) {
if (study != null) {
study.readBooks()
study.doHomework()
}
}
判空辅助工具
Kotlin 提供了 许多操作符供判空时使用
?. 在对象不为空时调用对应的方法
下面两个写法作用相同
if (a != null) {
a.doSomething()
}
a?.doSomething()
应用
fun doStudy(study: Study?) {
study?.readBooks()
study?.doHomework()
}
?:
这个有点像三元运算符,该操作符的左右两边各接收一个表达式,如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。
下面两个写法作用相同
val c = if (a ! = null) {
a
} else {
b
}
val c = a ?: b
用法示例
获取文本的长度
fun getTextLength(text: String?): Int {
if (text != null) {
return text.length
}
return 0
}
使用操作符简化
fun getTextLength(text: String?) = text?.length ?: 0
当 text 为空时,text?.length 会返回一个 null 值, 这个时候我们再借助 ?: 操作符让它返回0。
!!. 非空断言
这个操作符表明该对象一定不会为空,让编译器不报错。
fun printUpperCase() {
val upperCase = content!!.toUpperCase()
println(upperCase)
}
这样写确实能过编译,但是用前最好提醒下自己,有没有更好的方法。
let
let 函数后接 Lambda 表达式,会将调用的 对象作为参数传入
obj.let { obj2 ->
// 编写具体的业务逻辑
}
当Lambda表达式的参数列表中只有一个参数时, 可以不用声明参数名,可使用使用it关键字来代替
fun doStudy(study: Study?) {
study?.let {
it.readBooks()
it.doHomework()
}
}
推荐使用 let 对全局变量进行判空,因为使用 if 判空完进入执行代码块后,其他线程仍可能对该全局变量进行修改