Kotlin functional interfaces java compatiblity
The problem you're facing is due to missing SAM conversions, see [1], [2] for more information. In short, Java allows you to treat interfaces with one non-default, non-static method as functional interfaces. If this conversion were present in Kotlin, Kotlin lambda expressions could be implicitly converted to Java functional interfaces such as Function<T, R>
.
It's not possible to compile function literals to your own functional interface without changes to the compiler.
Your best bet given the status quo is to write a few conversion functions, which can be done very compactly in Kotlin:
object Functional
{
@JvmStatic fun <T> toKotlin(supplier: Supplier<T>): () -> T = supplier::get
@JvmStatic fun <T, R> toKotlin(function: Function<T, R>): (T) -> R = function::apply
@JvmStatic fun <T> toKotlin(function: BinaryOperator<T>): (T, T) -> T = function::apply
@JvmStatic fun <T> toKotlin(consumer: Consumer<T>): (T) -> Unit = consumer::accept
...
}
Let's apply this to a file Example.kt:
// passes an argument to the function and returns the result
fun call(function: (Int) -> Int, arg: Int): Int = function(arg)
From Java, you can then use them as follows:
import static yourpackage.Functional.toKotlin;
// in code:
ExampleKt.call(toKotlin(x -> 3 * x), 42);
Of course, if convenience is your goal, then you can overload your methods taking function parameters, to support both Kotlin and Java ways:
// Kotlin:
fun call(function: (Int) -> Int, arg: Int): Int = function(arg)
fun call(function: Function<Int, Int>, arg: Int): Int = call(toKotlin(function), arg)
// Java:
ExampleKt.call(x -> 3 * x, 42);