kotlin - 让 Kotlin 在将灵活/平台类型分配给非空类型时发出警告?

当从 Kotlin 调用不可为空注解的 Java 函数时,我们会得到灵活类型的返回值,用感叹号表示,例如字符串!.

Kotlin 允许将这些灵活的值分配给普通的非空类型,例如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"; }

}

...和下​​面的 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
}

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

这可能吗?

在此 2014 JetBrains blog post 的评论中,当他们引入平台/灵活类型时,听起来他们正计划添加一个选项来警告这些情况,但我无法找到任何进一步的信息。

最佳答案

是的,有可能从 Java 方法中获取编译器警告和/或错误,并强烈假设 if 方法没有 @NotNull 注释它是 @Nullable

怎么样? :) 您必须编写自己的 Idea Custom Inspection 插件

这里有一些有用的链接,供任何有足够经验构建自定义检查插件的人使用(可能我会是它的感激用户之一):

  1. 创意插件开发Quick Start Guide
  2. 所有现有创意的来源Kotlin Inspections (可能作为现有 null safety checks 的示例有用)

如果您是熟悉且经验丰富的 Idea 插件开发人员,那么可能不会花费很多时间。否则我不认为你将要达到的结果真的值得你花费时间。

我喜欢你的想法,但是在 kotlin 开发的早期阶段,AFAIK 曾尝试实现尽可能完整的 null 安全检查,结果出现了太多潜在的不安全分配.

附言如果您最终会构建该检查插件,请告诉我。我个人试图做到这一点,但就我而言,我必须首先了解更多关于 Idea 插件的信息。

https://stackoverflow.com/questions/45690785/

相关文章:

kotlin - 如何在 Kotlin 中运行编译的类文件?

kotlin - 如何在 Kotlin 中引用外部类的实例?

arrays - Kotlin 中的二维数组

android - 将支持库更新到 27.0.0 后,我的 fragment 中出现多个错误

rx-java - Kotlin 和 RxJava - 为什么我的 Single.zip() 没有编

android - Kotlin 和惯用的编写方式, 'if not null, else...'

java - java 10 和 kotlin 中的 “var”

kotlin - 如何从 Kotlin 中的字符串创建枚举?

android - Kotlin 中是否有类似 #region #endregion 的语法?

kotlin - 检查 Kotlin 中的字符串是否为空