Java interop: Unit closures required to return kotlin.Unit

Given this function:

object Tmp {
    @JvmStatic fun hello(f: () -> Unit) {

The following Java code doesn’t compile

public class Hello {
    public void asd() {
        Tmp.hello(() -> {

as it requires the closure to return Unit.INSTANCE.
Suggestion: Add @JvmVoid annotation to denote Units that should actually behave as void


I don’t understand why Unit is better than void or Void…

Someone can help me?

Unit is a type (unlike void) and has a value (unlike Void). This enable uniform treatment of Unit when it comes to generic classes. I.e. we don’t need another two types: a function that returns something and a function that returns void. It’s all one type: a function that returns something tat may be Unit.

Introducing void would pose many problems in areas like type inference, compositionality of any sort of functions, etc

1 Like

@abreslav Could you explain in which case it’s better to use Nothing over Unit ?

Thanks for response,
those are good points.
I’m interested to know how you will fix this issue.

Nothing is for a function/method that never returns,
i.e. System.exit() should return Nothing.

Also “throw” statement returns nothing.

All statements after a Nothing one are unreachable.

I’m not suggesting introducing void as a kotlin type, but rather annotating Unit for better Java interop. There is a straightforward translation from void to Unit which the compiler could do:

If void is covariant:

fun f(): @JvmVoid Unit {..}

would compile to two functions, one for kotlin, one for java:

public void f_kotlin(): Unit {
public void f_java() {

And if it’s contravariant the java version would just wrap void functions and pass in Unit.INSTANCE automatically.


This functionality is also required to maintain compatibility with code that inspects the return type of a method and will fail if it is not void. For example, in the Arquillian testing suite, the org.jboss.arquillian.junit.Arquillian.validatePublicVoidNoArgMethods() method checks to make sure that a test function annotated with @BeforeClass returns void. Without some way to generate the correct signature, Kotlin can’t be used with these libraries.

Hello, is there any solution so far to pass () -> {} in Java to Kotlin function as an argument, which is declared as () -> Unit?


Any updates on this? Learning Kotlin second day and facing this already. The best I come up with is

fun created(callback: (s: Subscriber) -> Unit)  {

Java (ugly return null):

subscriber.created(s -> {
    System.out.println("User " + s + " was created");
    return null;

Any better solution for this?

Better no.
Advise which is not like by kotlin itself:
If you want to be java-compatible, declare your lambdas using java-functional interfaces.
Kotlin has fun interfaces themselves, but I didn’t look into them yet

for everyone stumbling over this problem, i use following workaround.

My kotlin function is this:

fun justSomeTest(f:()->Unit){}

To call it in Java, it would look like this:

bla.justSomeTest(()->{return null;});

But with adding an overload in kotlin with the Java Interfaces like this:

fun justSomeTest(f:Runnable)=justSomeTest { }

the java code becomes the following:


Obviously this also works with the Java interfaces Function, Consumer, Supplier etc the same way