作者:手浪用户2602928711 | 来源:互联网 | 2022-12-08 16:44
我在kotlin中处理应用程序,但需要有一个很好的java支持.我发现的问题是kotlin的功能.
这就是我以前做的事情
fun test(loader: (String) -> Int)
但是这会从kotlin库编译成一个Function1,因为罐子大小我没有直接包含在jar中的kotlin库,这使得Java开发人员更难,因为他们必须下载kotlin库才能使用它方法.
我尝试使用java中的Supplier或Function接口,但我发现kotlin开发人员要困难得多,因为你必须提供更多的变量类型和null检查以及通用参数,这很痛苦.
还尝试创建我自己的界面
@FunctionalInterface
interface Function: Function {
operator fun invoke(p: T): R
}
和功能
fun test(loader: Function)
但它与默认的java Function接口相同
因此唯一可行的方法是让编译器将我的原始函数编译到我自己的函数接口而不是kotlin的函数接口.但我不知道该怎么做.
1> TheOperator..:
您面临的问题是由于缺少SAM转换而引起的,有关更多信息,请参见[1],[2]。简而言之,Java允许您将具有一种非默认,非静态方法的接口视为功能接口。如果Kotlin中存在此转换,则可以将Kotlin lambda表达式隐式转换为Java功能接口,例如Function
。
如果不更改编译器,就无法将函数文字编译为您自己的函数接口。
考虑到现状,最好的选择是编写一些转换函数,这些函数可以在Kotlin中非常紧凑地完成:
object Functional
{
@JvmStatic fun toKotlin(supplier: Supplier): () -> T = supplier::get
@JvmStatic fun toKotlin(function: Function): (T) -> R = function::apply
@JvmStatic fun toKotlin(function: BinaryOperator): (T, T) -> T = function::apply
@JvmStatic fun toKotlin(consumer: Consumer): (T) -> Unit = consumer::accept
...
}
让我们将其应用于文件Example.kt:
// passes an argument to the function and returns the result
fun call(function: (Int) -> Int, arg: Int): Int = function(arg)
在Java中,您可以按以下方式使用它们:
import static yourpackage.Functional.toKotlin;
// in code:
ExampleKt.call(toKotlin(x -> 3 * x), 42);
当然,如果您的目标是方便,那么可以使用函数参数重载方法,以支持Kotlin和Java方式:
// Kotlin:
fun call(function: (Int) -> Int, arg: Int): Int = function(arg)
fun call(function: Function, arg: Int): Int = call(toKotlin(function), arg)
// Java:
ExampleKt.call(x -> 3 * x, 42);