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

时间:2017-08-15 10:09:47

标签: kotlin nullable non-nullable

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

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的评论中,当他们介绍平台/灵活类型时,听起来他们计划添加一个选项来警告这些情况,但我还没有找到任何进一步的关于那个的信息。

3 个答案:

答案 0 :(得分:1)

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

  

Java中的任何引用都可能为null,这就是Kotlin的要求   对于来自Java的对象,严格的null安全性是不切实际的。类型   Java声明在Kotlin中被特别处理并被调用   平台类型。对于这些类型,放宽空检查,以确保安全   对它们的保证与Java相同

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

  

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

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

答案 1 :(得分:1)

是的,有可能为Java方法的任何分配获取编译器警告和/或错误,并强烈假设如果方法没有@NotNull注释它是@Nullable

如何? :) 您必须编写自己的Idea Custom Inspection插件

这里有一些有用的链接,供有经验的人建立自定义检查插件(可能我会成为感恩的用户之一):

  1. Idea插件开发Quick Start Guide
  2. 所有现有构思Kotlin Inspections的来源(可能作为现有null safety checks的示例有用)
  3. 如果您是熟悉且经验丰富的Idea插件开发人员,那么可能不会花费很多时间。否则,我不认为你将要实现的结果真的值得你花费的时间。

    我喜欢你的想法,但是在kotlin开发的早期阶段,AFAIK尝试实现尽可能完整的空安全检查,并且转为如此,有太多可能不安全的分配。

    P.S。如果您最终构建该检查插件,请告诉我。我个人试图制作它,但在我的情况下,我将首先了解有关Idea插件的更多信息。

答案 2 :(得分:-1)

表示非空字符串 -

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

for null Strings -

你可以在if条件下检查null。