Kotlin空安全类型之平台类型

前言

众所周知,Kotlin的空安全很方便,能避免绝大部分的空安全问题
一般类型分为:
可空类型如 String?
不可空类型 String

其中可空类型的String?可以赋值null或String类型的值,在使用时必须显式的进行空处理
而不可空类型的String,只能赋值String类型,无法向其赋值null,使用时无需空处理,也不会遇见空指针异常
但为什么我上面说能避免绝大部分的空安全问题呢?是因为Kotlin为了兼容其他语言,还有对应语言平台的平台类型 String!

还有延迟初始化的类型
lateinit var String

当然lateinit不是本篇的重点,我们接下来详细了解一下平台类型

正文

平台类型无法通过Kotlin直接声明出来,只会在使用对应平台语言时出现,比如在jvm平台上使用Java语言

 

我们在Kotlin中使用Java的api时,如果Java的api没有加空安全注解的话,Kotlin就会将其类型识别为平台类型

Kotlin空安全类型之平台类型_第1张图片

这时我们可以将这个类型的值当作可空类型处理,也可以当作不可空类型处理(就像在Java中那样)
而如果其的值为null,我们没有?.而是.调用后就会触发空指针异常

空指针触发情景

1.将平台类型当作不可空类型使用
比如:
Java.getString().length

由于直接获取平台类型 的属性值,而getString()返回了null,此时就会触发空指针

2.将平台类型传递到方法的非空参数中
比如:

fun a(s:String){}
a(Java.getString())

Kotlin会在编译时给方法的非空参数加上以下校验代码:
Intrinsics.checkNotNullParameter(s, "s");//如果s为null就会抛异常

Kotlin空安全类型之平台类型_第2张图片

3.可能会成为隐藏的地雷
比如:

        var imei: String = ""
        try {
            imei = getImei()
        } catch (e: Exception) {
            ...
        }
        imei.length()

这里可能会有错觉,如果imei抛异常,就不会修改原有的空字符串imei
但如果getImei()返回了null,这样没有抛异常,且也将imei给赋值为了null,在后续使用的时候才会触发空指针异常

解决方案

1.给Java api增加 @Nullable 或 @NotNull 注解
他们表示Java中类型的空安全性,Kotlin可以直接识别注解,确定其空安全类型
Java中可以在使用的过程中提示一些空安全警告信息

2.尽量将Java api转为Kotlin api使用
这样可以避免平台类型的出现,完善空安全类型

3.如果可以,尽量将平台类型赋值给可空类型或当作可空类型使用

扩展

修改设置可以直接看到Kotlin推断的类型

Kotlin空安全类型之平台类型_第3张图片

修改完就会变成这样

你可能感兴趣的:(Kotlin,Adnroid,kmm,kotlin,开发语言,java,android,kmm)