让Kotlin警告将灵活/平台类型分配给非null类型?

Sni*_*kow 26 nullable non-nullable kotlin

当从Kotlin调用非可空性注释的Java函数时,我们得到灵活类型的返回值,用感叹号表示,例如String!.

Kotlin默默地允许将这些灵活值分配给正常的非null类型,例如String,这可能在运行时导致NullPointerExceptions.

我更希望得到编译器警告或错误的此类分配.或者,将平台类型视为等效于可空类型(例如String?).

例如,使用此Java代码:

import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

public class NullTest {

    private String maybe() {
        if (SystemClock.elapsedRealtimeNanos() % 2 == 0) {
            return null;
        }
        return "ok";
    }

    public String annotatedNothing()            { return maybe(); }
    @Nullable public String annotatedNullable() { return maybe(); }
    @NonNull  public String annotatedNonNull()  { return "ok"; }

}
Run Code Online (Sandbox Code Playgroud)

...以及以下Kotlin代码,我想在两个新行上看到错误(请参阅注释):

fun testnulls() {
    val obj = NullTest()

    val nullExact: String  = obj.annotatedNullable() // already gives an error
    val nullMaybe: String? = obj.annotatedNullable()
    val nullInfer          = obj.annotatedNullable()

    val okayExact: String  = obj.annotatedNonNull()
    val okayMaybe: String? = obj.annotatedNonNull()
    val okayInfer          = obj.annotatedNonNull()

    val bareExact: String  = obj.annotatedNothing() // I want a compiler error here
    val bareMaybe: String? = obj.annotatedNothing()
    val bareInfer          = obj.annotatedNothing()

    print("length " + nullExact.length)
    print("length " + nullMaybe.length) // already gives an error
    print("length " + nullInfer.length) // already gives an error

    print("length " + okayExact.length)
    print("length " + okayMaybe.length) // already gives an error
    print("length " + okayInfer.length)

    print("length " + bareExact.length)
    print("length " + bareMaybe.length) // already gives an error
    print("length " + bareInfer.length) // I want a compiler error here
}
Run Code Online (Sandbox Code Playgroud)

关键是这将迫使我添加空检查,或!!确保我至少必须明确它.

这可能吗?

2014年JetBrains博客文章的评论中,当他们介绍平台/灵活类型时,听起来他们计划添加一个选项来警告这些情况,但我还没有找到任何进一步的信息.

oia*_*kyi 0

Kotlin文档描述了这种具体情况:

Java 中的任何引用都可能为 null,这使得 Kotlin 严格的 null 安全要求对于来自 Java 的对象来说不切实际。Java 声明的类型在 Kotlin 中被特殊对待,称为平台类型。对于此类类型,空检查很宽松,因此它们的安全保证与 Java 中的相同

不幸的是,这意味着无法在编译期间发出警告。一线希望是 Kotlin 至少会阻止 null 在运行时传播。

当我们调用平台类型的变量上的方法时,Kotlin 在编译时不会发出可空性错误,但调用可能会在运行时失败,因为空指针异常或 Kotlin 为防止传播空值而生成的断言

如果我不控制所使用的 Java 库的源代码,我会将所有结果视为可能可为空,除非很明显它们不能为空。

  • 是的,我知道这是记录在案的行为,但我希望有一个选项可以更改它,或者可以在 IntelliJ/Android Studio 等中对其进行代码检查。空安全类型的要点(至少是我能看到的最大好处)是_不必_考虑某些内容是否可以为空——如果我弄错了,编译器会朝我大喊大叫。我想我只是不喜欢平台类型的概念。本质上,我希望编译器帮助我执行您的建议:“将所有 [Java] 结果视为可能为空”,除非我说(`!!`)它们不是。 (4认同)