一. 在Kotlin 中, 默认所有的参数和变量都不可为空
看一个代码块:
interface Learn{
fun readBooks()
fun doSchoolwork()
}
fun doLearn(learn: Learn){
learn.readBooks()
learn.doSchoolwork()
}
这里doLearn()传入的参数一定不为空, 如果尝试向其传入一个null参数, 会提示报错。如下图所示
也就是说,Kotlin 将空指针异常的检查提前到了编译期, 写入代码时就不能通过。
二. 如果一定需要某个参数或变量为空呢? Kotlin提供了另外一套为空的类型系统。
语法是: 在类名后面加上一个问号?
例如: Int表示不可为空的整型, Int?表示可为空的整型, String表示不可为空的字符串, String?表示可为空的字符串。
注意: 这时候可以传入null, 但是在方法内要加上判断处理不为空,如下所示:
fun doLearn(learn: Learn?){
if(null != learn) {
learn.readBooks()
learn.doSchoolwork()
}
}
如果不加判断,则报错
三. 判空辅助工具
首先学习最常用的?.操作符,它的意思是当对象不为空时正常调用相应方法, 当对象为空时什么都不做。
前面写的if(null != learn){}, 可以这样修改成这样: learn?. 也就是说, doLearn()方法可以这样修改:
fun doLearn(learn: Learn?){
learn?.readBooks()
learn?.doSchoolwork()
}
借助?. 将if判断语句去掉了。
其次,现在再学习一个非常有用的?:操作符。 这个操作符的左右两边都接收一个表达式, 如果左边表达式的结果不为空就返回左边的结果, 否则就返回右边表达式的结果。
看一段代码:
val c=if(a != null){
a
}else{
b
}
使用?:操作符可以简化成:
val c = a ?: b
现在,我们将?.和?:结合起来使用, 编写一个方法用来获得一段文本的长度, 传统写法是这样写:
fun getTextLength(text: String?): Int{
if(null != text){
return text.length
}
return 0
}
如果用操作符 就可以这样写:
fun getTextLength(text: String?) = text?.length ?: 0
这两种写法实现的效果是一样的: 当text不为空就返回它的长度,否则返回0
四 非空断言工具
看一段代码:
代码 编译不能通过! 因为printUpperCase()不知道外部已经对content变量进行了非空检查, content 在调用toUpperCase()方法时,认为这里存在空指针风险。
如果要想强行编译通过, 可以使用非空断言工具,语法是在对象的后面加上!! 如下所示:
注意: 这种写法有风险, 它告诉Kotlin编译环境, 不用你来检查空指针了,如果出现问题,你直接抛出空指针异常, 后果由我承担。