Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I override kotlin method which returns Unit type in Java

Main Question: How can I override kotlin method in java which returns Unit type?

I'm trying to use kotlin library in java and there is a method which name is override fun invoke(): Unit that I have to implement.

but, java compiler keep telling me return type void is not compatible with Unit.

I tried public Unit invoke() { return Unit.INSTANCE; } in java but occurs compile error.

invoke()' in 'myproject' clashes with 'invoke()' in 'library'; 
attempting to use incompatible return type

kotlin interface (in library)

interface MessageHandler<M : Message> : (Message) -> Unit {

  override fun invoke(message: Message): Unit =
    if (messageType.isAssignableFrom(message.javaClass)) {
      println("invoked ${message.javaClass.simpleName}")
    } else {
      throw IllegalArgumentException("Unsupported message type ${message.javaClass.simpleName}")
    }

}

java abstract class (in my project)

public abstract class AbstractMessageHandler<T extends Message> implements MessageHandler<T> {

    @Override
    public void invoke(@NotNull Message message) {
        //this is where the compile error occurs.
    }
}

error message

(Message) in AbstractMessageHandler cannot implement invoke(P1) in Function1
    public void invoke(@NotNull Message message) {
                ^
  return type void is not compatible with Unit
  where P1,R are type-variables:
    P1 extends Object declared in interface Function1
    R extends Object declared in interface Function1
like image 472
Junyoung Oh Avatar asked Sep 06 '25 16:09

Junyoung Oh


1 Answers

Looks like a 4-year old unresolved bug: https://youtrack.jetbrains.com/issue/KT-15964

Quoted:

I don't think this is possible now because of compatibility with older binaries. We'll see what we can do, thank you for the report.

An ugly workaround would be to use the nullable type Unit?:

interface TestA<out T> {
    fun foo(): T
}

abstract class TestB : TestA<Unit?> {
    override fun foo(): Unit? {
        // ...
        return Unit
    }
}

With this, you won't be required to override foo in a Java subclass. If you want to override it though, the signature in the Java subclass should be public Unit foo().

If you don't control the library, I'm not sure there's much you can do.

like image 80
Adam Millerchip Avatar answered Sep 09 '25 04:09

Adam Millerchip