Kotlin调Java可能返回为空的函数
Java 中的任何引用都可能是 null,这使得 Kotlin 对来自 Java 的对象要求严格空安全是不现实的。 Java 声明的类型在 Kotlin 中会被特别对待并称为平台类型。
当把一个平台值赋值给一个 Kotlin 变量时,可以选择我们期望的类型(可空或非空类型):
1 | val nullable: String? = item // 允许,没有问题 |
如果我们选择非空类型,编译器会在赋值时触发一个断言。这防止 Kotlin 的非空变量保存空值。当我们把平台值传递给期待非空值等的 Kotlin 函数时,也会触发断言。 总的来说,编译器尽力阻止空值通过程序向远传播(尽管鉴于泛型的原因,有时这不可能完全消除)。
如果我们选择非空类型,编译器会在赋值时触发一个断言。这防止 Kotlin 的非空变量保存空值。当我们把平台值传递给期待非空值等的 Kotlin 函数时,也会触发断言。 总的来说,编译器尽力阻止空值通过程序向远传播。
只有在Java层给方法加上@Nullable
之后才会提示返回值可空。
空安全实际遇到的问题
一开始有一个Java的旧类,一直没有改动过,但是有需求要有不同的实现,所以需要把类的各个方法抽象为接口,接口类用Kotlin实现,接口的实现类还是原来的Java类,其中有个方法在Kotlin的接口中返回值是非空的String,java实现类中返回值是String,但是没有加@NotNull的注解,也就是可空的。
在实际调用这个方法的时候,当java实现类中返回null,就会报空指针异常。
Nullable注解应该是哪个库哪个包的注解?
具有可空性注解的Java类型并不表示为平台类型,而是表示为实际可空或非空的 Kotlin 类型。编译器支持多种可空性注解,包括:
JetBrains (org.jetbrains.annotations 包中的 @Nullable 和 @NotNull)
Android(com.android.annotations 和 android.support.annotations)
JSR-305(javax.annotation,详见下文)
FindBugs(edu.umd.cs.findbugs.annotations)
Eclipse(org.eclipse.jdt.annotation)
Lombok(lombok.NonNull)。
你可以在 Kotlin 编译器源代码中找到完整的列表。