空安全
因为在kotlin中,默认的类中是无法用null进行初始化,所以可能出现NPE的范围大大缩小了。
var s: String = null
这样的语句是无法通过编译的。可能出现NPE的地方官网已经为我们说明:
- 显式调用 throw NullPointerException()
- 使用了下文描述的 !! 操作符
- 外部 Java 代码导致的
- 对于初始化,有一些数据不一致(如一个未初始化的 this 用于构造函数的某个地方)
对一些属性而言,我们希望在合理的地方进行初始化,变会有了如下的语句:
var s: String? = null
对s调用可以使用以下方法处理
- !!
s!!.length
在java中它就是
if(s!=null){
return s.length
}else {
throw new NullPointerException()
}
- ?.
s?.length
在java中它就是
if(s!=null){
return s.length
}else {
return null
}
-Elvis 操作符
s?.length ?: -1
这句可以分为 A ?: B
,只有在A=null时,执行B
同时因为 throw 和 return 在 Kotlin 中都是表达式,所以它们也可以用在 elvis 操作符右侧。这可能会非常方便,例如,检查函数参数:
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException("name expected")
// ……
}
异常
kotlin中抛出异常使用throw Excetion(msg: String)
,同时使用try-catch-finally模块捕获异常,可以有零到多个 catch 块。finally 块可以省略。 但是 catch 和 finally 块至少应该存在一个。
不同于java,kotlin中的try是一个表达式,可以得到返回值,try-表达式的返回值是 try 块中的 最后一个表达式或者是(所有)catch 块中的最后一个表达式。 finally 块中的内容不会影响表达式的结果。
val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }
java中对异常会强制开发人员try-catch或throw,这里则不强制开发人员去处理异常(Rhett:可能我理解不够深,我还是觉得java的处理方式比较好)。
Nothing类
在 Kotlin 中 throw 是表达式,所以你可以使用它(比如)作为 Elvis 表达式的一部分:
val s = person.name ?: throw IllegalArgumentException("Name required")
throw 表达式的类型是特殊类型 Nothing。 该类型没有值,而是用于标记永远不能达到的代码位置。 在你自己的代码中,你可以使用 Nothing 来标记一个永远不会返回的函数:
throw IllegalArgumentException(message)
}
当你调用该函数时,编译器会知道执行不会超出该调用:
println(s) //能达到这里说明s初始化已经完成