动机:
在我们的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而崩溃。正如我在下面提到的,问题更多的是访问本机库代码,而不是我自己的扩展。
请帮忙吗?
答案 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)