【问题标题】:How to call Kotlin standard library function from Java?如何从 Java 调用 Kotlin 标准库函数?
【发布时间】:2018-08-08 03:29:52
【问题描述】:

动机:

在我们的 Android 项目中,我们有很多验证,例如 str != null && !str.isEmpty(),所以我决定将它们重构为辅助方法。 我暂时使用以下类作为助手:

public class StringUtil {
    public static boolean isNullOrEmpty(@Nullable String str) {
        return str == null || str.isEmpty();
    }
}

问题:

我们已经有了一个字符串的帮助类,用 Kotlin 编写(比如 String.kt)。 所以,这并不清楚是否有两个助手(一个在 Java 中,一个在 Kotlin 中)。

我尝试了什么:

在 String.kt 中复制过去 isNullOrEmpty() 的幼稚方法没有成功,因为 $reciever 为空,所以它崩溃了。

其次,我尝试使用来自ko​​tlin.text(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-null-or-empty.html)的Kotlin原生isNullOrEmpty():

public inline fun CharSequence?.isNullOrEmpty(): Boolean

但我不知道如何从 Java 中调用它。此页面 (https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html) 不提供任何建议。

问题不在于 Accessing Kotlin extension functions from Java。我的扩展非常明显,但由于空接收器而崩溃。正如我在下面提到的,问题更多是关于访问本机库代码,而不是我自己的扩展。

有什么帮助吗?

【问题讨论】:

  • @Moira 我的问题是关于访问本机库代码,而不是我自己的扩展,请在将其标记为重复之前仔细阅读问题。
  • 您能否澄清一下“$receiver 为空,所以它崩溃了”的确切含义?如果您为可空接收器类型 (String?.isNullOrEmpty) 声明扩展函数,则可以将 null 作为 $receiver 参数传递给它们。
  • 嗯,这不是本机代码,它是标准库,它是关于扩展函数的(这是否是您的代码无关紧要)。在大多数情况下,这是重复的。 yole 指出,由于@InlineOnly 将编译后的函数标记为synthetic,Java 无法访问一些 stdlib 函数。
  • 或者你可以使用这个:developer.android.com/reference/android/text/…

标签: java android kotlin


【解决方案1】:

一些标准库函数,包括这个函数,都标有@InlineOnly 注解,这使得Java 无法访问它们。对于大多数其他功能,您可以完全按照作为副本链接的问题中的描述访问它们。

【讨论】:

  • 感谢您的解释!顺便说一句,我没有成功将它移动到扩展,因为崩溃。我会尝试使用您对String? 的建议。
【解决方案2】:

在@yole 的建议下,我终于设法将代码正确地转换为扩展:

fun String?.isNullOrEmpty(): Boolean = (this == null || this.isEmpty())

因此,问题在于将扩展名定义为String,而不是String?,这会导致$receiver 崩溃。 (Kotlin 在翻译成 Java 时会生成隐藏的非空验证,参见https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#null-safety)

另外,标有@InlineOnly 的标准库函数可以通过自定义扩展从Java 访问。

fun String?.isVoid(): Boolean = this.isNullOrEmpty()

我的问题是对? 的误解。我首先尝试了这个:

fun String?.isVoid(): Boolean? = this?.isNullOrEmpty()

正如@Moria 提到的,请注意? 的行为 - 如果b 不是null,b?.method 将返回b.method,否则返回null (@987654322 @)

【讨论】:

  • @Moira 当我尝试将其用作fun String?.isVoid(): Boolean = this?.isNullOrEmpty() 时,我无法编译并出现错误Type mismatch: inferred type is Boolean? but Boolean was expected
  • 您不要将它与?. 一起使用,而是将其用作this.isNullOrEmpty(),因为该函数可以与可空类型一起使用。 ?. 强制函数使用非空值,如果为空则返回空(这不是你想要的)
猜你喜欢
  • 2011-02-21
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 2019-05-30
  • 2019-04-05
  • 1970-01-01
相关资源
最近更新 更多