注:文中demo的kt版本是1.7.10
一、kotlin语言中的可空性设计
在Java语言中的NPE(NullPointerException)可以说非常常见,而且诟病已久。
kotlin做为后起之秀,在空指针的问题上进行了升级,即:把本来运行时才能暴露出来的空指针问题,前置到编译期就能让开发者发现,在编写代码时就显式的声明变量类型是不是可空类型,如果将可空类型赋值给不可空类型,或者不可空类型赋值给可空类型,就会报编译时错误,从而减少在运行时抛出异常的概率。
可空类型赋值给不可空类型编译时错误:
二、kotlin调用java时的可空性
2.1 kotlin调用java时的平台类型?
kotlin中调用Java中的变量,会被识别为平台类型,平台类型就像java中的变量一样,可能为空,也可能不为空,需要开发人员在写逻辑代码时正确的理解变量是否可能为空,如果可能为空就必须要进行判空处理,否则就会报NPE,导致程序异常退出。
举例,在kt代码中,调用一个java中的变量:
java代码:
public class LaunchInfo {
public String type;
}
kotlin调用java的代码:
fun main() {
println("hello kt!")
val launchInfo = LaunchInfo()
// new出来的launchInfo对象的type字段默认为null,
// 但是在kt中调用java中为null的变量,并没有任何提醒
var launchType: String = launchInfo.type
}
如上代码,最终的NPE异常是在运行时被发现,最终其实比直接使用java还多出来一种出现NPE异常的场景,报错如下:
hello kt!
Exception in thread "main" java.lang.NullPointerException: launchInfo.type must not be null
at com.yyg.kt.HelloKtKt.main(HelloKt.kt:22)
at com.yyg.kt.HelloKtKt.main(HelloKt.kt)
以上问题是在真实开发过程中遇到过的,本质上还是对kt调用java的可空性处理语法规则不熟悉+逻辑处理不当引起。需要在kt调用java时小心谨慎关注平台类型的可空性,避免在kt调用老的java代码时,报运行时错误,发现时间晚,造成线上问题。
java中不加任何修饰符,被kt调用时可能是可空类型,也可能为空类型:
2.1 在java中使用注解的方式让kt能识别成可空类型
对于2.1的问题,如果给LaunchInfo的type字段加上@Nullable注解的话,那么在kt代码中是能在编译期报错的。
java中增加注解的变量类型,在kt中被识别类型对应如下: