javakotlininterfacevalue-class

Using kotlin method with value class in signature from Java code


I have such Kotlin entity

value class EntityId(val id: Long) {}

and some service's interface

interface Service {
    fun do(entityId: EntityId)
}

and its implementation.

But when I use the interface from Java code like this

{
    ...
    EntityId id = new EntityId(1L);
    service.do(id) // service is interface here 
}

I receive the compilation error. But it's pretty understandable behaviour because Kotlin compiler generates fun do(entityId: Long) from the sources. Okay, let use something like this service.do(1L). Another issue will occur:

java: cannot find symbol
symbol:   method do(long)

I guess it occurs because interface actually isn't changed during compilation. I found a single way - replace value class with data class but I would have value class.

Maybe, does some workaround exist for such a case?


Solution

  • You could overload the function that takes value class with a function that takes Long and calls the original under the hood.

    Kotlin

    @JvmInline
    value class EntityId(val id: Long)
    
    interface Service {
        fun process(entityId: EntityId)
        fun process(entityId: Long)
    }
    
    class ServiceImpl : Service {
        override fun process(entityId: EntityId) {
        }
    
        override fun process(entityId: Long) {
            process(EntityId(entityId))
        }
    }
    

    Then you can call it from Java with a Long literal:

    Service service = new ServiceImpl();
    service.process(42L);