据机构统计,Android系统崩溃率最高的异常是空指针异常(NullPointerException)
是因为这是一种不受编译器检查,而靠程序员主动判断的避免的异常
如果函数传入一个null参数,很可能会发生空指针异常
kotlin利用编译时判空检查几乎杜绝了空指针异常
fun doStudy(study: Study) {
study.readBooks()
study.doHomework()
}
kotlin 默认所有参数和变量不为空,如果传入null,会提示错误:
doStudy(null) // 提示错误
如果需要空参数怎么办
可空类型:在类型名后面加一个问号:
如: Int 不可空, Int? 可空整型
如 fun doStudy(study: Study?) {…} 并提示需要处理空类型
判空辅助工具
1 ?.
当为空时,什么也不做,不为空则继续执行
fun doStudy(study: Study) {
study?.readBooks()
}
2 ?:
操作符左右各一个表达式, 左边不为空则返回左边,否则返回右边
val c = a ?: b
应用
fun getTextLength(text: String?): Int {
if (text !=null) {
return text.length
}
return 0
}
简化:
fun getTextLength(text: String?) = text?.length ?: 0
有时kotlin的检查也会出现错误,逻辑上已经处理,但是kotlin编译器不知道导致编译失败,如:
var content: String? = "hello"
fun main() {
if (content != null) {
printUpperCase()
}
}
fun printUpperCase() {
val upperCase = content.toUpperCase()
println(upperCase)
}
虽然逻辑上已经判空,但是编译器不知道,会编译不通过
,这时可以使用!!
content!!.toUpperCase()
函数let
优化
fun doStudy(study:Study?) {
study?.let{ stu ->
stu.readBooks()
stu.doHomework()
}
}
let 函数将study对象本身作为参数传递到Lambda表达式,此时study肯定不为空,可以放心调用
Lambda中只有一个参数时,可以不用声明:用it关键字替代
fun doStudy(study: Study?) {
study?.let {
it.readBooks()
it.doHomework()
}
}
let 可以处理 全局变量 判空问题, 而if不可以,因为全局变量可以随时被改变