如何从Java调用Kotlin标准库函数?

时间:2018-02-28 09:44:52

标签: java android kotlin

动机:

在我们的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为空,所以它崩溃了。

其次,我尝试使用kotlin.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 。我的扩展是完全明显的,但它因为null-receivier而崩溃。正如我在下面提到的,问题更多的是访问本机库代码,而不是我自己的扩展。

请帮忙吗?

2 个答案:

答案 0 :(得分:2)

某些标准库函数(包括此函数)使用@InlineOnly注释进行标记,这使得它们无法从Java中访问。对于大多数其他功能,您可以完全按照链接为重复的问题中的描述来访问它们。

答案 1 :(得分: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

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

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

我的问题在于对?的误解。我先试了一下:

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

正如@Moria所提到的,请注意? - b?.method的行为如果b不是 null ,则会返回b.method,并且 null 否则(https://kotlinlang.org/docs/reference/null-safety.html#safe-calls