让Kotlin警告灵活/平台类型赋值为非空类型?

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

Kotlin默默地允许将这些灵活的值分配给一个正常的非空类型,例如String ,在运行时可能会导致NullPointerException异常。

我宁愿为这样的任务得到编译器警告或错误。 或者,将平台类型视为等价于可空类型(例如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博客文章的评论中,当他们介绍平台/灵活类型时,听起来他们正计划添加一个选项来警告这些情况,但是我一直没有找到任何进一步的信息。

Kotlin 文档描述了这个确切的案例:

Java中的任何引用都可能为空,这使得Kotlin对来自Java的对象的严格无效安全的要求是不切实际的。 Java声明的类型在Kotlin中被专门处理,并被称为平台类型。 这种类型的空检查是放松的,所以它们的安全保证和Java一样

不幸的是,这意味着在编译的时候没有办法发出警告。 一线希望Kotlin至少可以防止null在运行时传播。

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

如果我不控制我使用的Java库的源代码,我把所有的结果视为可能为空,除非它们显然不是这样。

是的,如果方法没有@NotNull注解,它是@Nullable ,那么可以从Java方法的任何赋值中获得编译器警告和/或错误。

怎么样? 🙂 你将不得不编写自己的Idea Custom Inspection插件

下面是一些有经验的人建立自定义检测插件的一些有用的链接(可能我会在其感激的用户之中):

  1. Idea插件开发快速入门指南
  2. 所有现有的Idea Kotlin检查的来源 (作为现有的无效安全检查的例子可能是有用的)

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

我喜欢你的想法,但是AFAIK在kotlin开发的早期阶段试图实施尽可能完全无效的安全检查,并且这样做的结果是,有太多可能不安全的任务。

如果你最终将建立这个检查插件,请让我知道。 我个人尝试过,但在我的情况下,我将首先了解更多关于Idea插件。

对于非空字符串 –

检查isEmpty()。 您将无法在该方法中传递非空字符串。 所以它是安全的。

为null字符串

你可以检查null条件。