如何使用 Kotlin 中的 Java 不可空元素集合?

How do I use Java collections of non-nullable elements from Kotlin?

使用 Kotlin 具有的可空性互操作自动化,这样的方法在 Kotlin 中获得正确的签名:

@NonNull
public String foo(@NonNull String bar) {
    return "bar";
}

现在将原理提升到集合(或其他泛型,我猜):

@NonNull
public Set<String> foo(@NonNull Collection<String> bar) {
    return new HashSet<String>();
}

这在 Kotlin 中显示为

foo(bar: (Mutable)Collection<String!>) : (Mutable)Set<String!>

我对 (Mutable) 没意见,但我如何去掉类型参数中的平台类型?也就是说,我该如何编写或注释 Java 函数,以便我从 Kotlin 中看到 Set<String>(或 Set<String?>)?

不允许使用 Set<@NonNull String>(“'@NonNull' 不适用于类型使用”)。

如果有所不同,我会使用 Findbugs 注释(通过 Spotbugs)。我的观点是 (Java) 库提供者的观点,他希望尽可能无缝地使用 Kotlin。

原来这是我使用的注释的实现问题,而不是概念上的问题。

自 Spotbugs Annotations 3.1.2 起,注释 @NotNull@NonNull 未针对目标 ElementType.TYPE_USE.

声明

Jetbrains annotations 使用该标志声明,它们可以用于类型参数:

@NotNull
public Set<@NotNull String> foo(@NotNull Collection<@NotNull String> bar) {
    return new HashSet<>();
}

虽然这在 Java 中看起来 有点 笨拙,但我们得到了所需的 Kotlin 签名:

foo(bar: (Mutable)Collection<String>) : (Mutable)Set<String>

请注意,注释类型参数需要源语言水平Java 8+。


关于 Android 和其他卡在低语言水平的情况的注释。由于注释具有保留级别 CLASS,如果应用程序使用这样注释的库,我预计不会出现任何运行时问题。不过,我还没有测试过;评论赞赏。