If I have a Kotlin function
fun f(cb: (Int) -> Unit)
and I want to call f
from Java, I have to do it like:
f(i -> {
dosomething();
return Unit.INSTANCE;
});
which looks very ugly. Why can't I just write it like f(i -> dosomething());
, since Unit
in Kotlin is equivalent to void
in Java?
I use this approach for Kotlin & Java. The methods of MyKotlinClass you will see in Java, in Kotlin you will see both methods (class method + extension function).
Unit
in Kotlin is mostly equivalent tovoid
in Java, however only when the rules of the JVM allow it.Functional types in Kotlin are represented by interfaces like:
When you declare
(Int) -> Unit
, from Java's point of view this is equivalent toFunction<Integer, Unit>
. That's why you have to return a value. To work around this problem, in Java there are two separate interfacesConsumer<T>
andFunction<T, R>
for when you don't have/have a return value.The Kotlin designers decided to forgo the duplication of functional interfaces and instead rely on compiler "magic". If you declare a lambda in Kotlin, you don't have to return a value because the compiler will insert one for you.
To make your life a little bit easier, you can write a helper method that wraps a
Consumer<T>
in aFunction1<T, Unit>
:Usage:
Fun fact: The special handling of
Unit
by the Kotlin compiler is the reason you can write code like:or
Both methods have return type
void
in the generated bytecode but the compiler is smart enough to figure that out and allow you to use return statements/expressions anyway.