https://kotlinlang.org logo
Title
m

Marcus Brito

11/19/2021, 1:59 PM
🧵 hey guys, I’m facing an issue with Kotlin type system and generic class types. In particular, I’m working with Akka Typed and its
ReceiveBuilder#onMessage
signature.
The problem is that the behavior itself is generic:
private class MyBehavior<T> : AbstractBehavior<Message<T>>
the receive builder then has a method with the signature:
onMessage(type: Class<T>, handler: Function<T, Behavior<T>>)
type
is supposed to be a subtype of
T
, but with the generics argument in there I can’t get it to compile without an explicit cast
is that the only way, or is there a better solution?
the real code:
e

Emil Kantis

11/19/2021, 2:04 PM
does this work?
fun <T, Y: Class<T>> onMessage(type: Y, handler: Function<T, Behavior<T>>)
m

Marcus Brito

11/19/2021, 2:04 PM
without the cast I’ll get a type mismatch
@Emil Kantis not really; the problem is that
::class
will always get the star projection, not the generic variant I need.
in Java I can do
.onMessage(SubType.class, this::handler),
where handler is
private Behavior<...> handler(SubType<T> msg)
I get an unchecked generics warning, but it does work; apparently in Kotlin the best I can do is creating that var with the class object
I tried defining an extension method with a reified type param, but it’s also quite verbose — the compiler doesn’t infer the right types from the handler alone.
that is:
inline fun <T, reified U : T> ReceiveBuilder<T>.onMessage(noinline handler: (U) -> Behavior<T>): ReceiveBuilder<T> {
    return onMessage(U::class.java, handler)
}
and then I can do:
return newReceiveBuilder()
            .onMessage<MessageProcessorDriverMessage<T>, MessageProcessorDriverMessageReceived<T>> { onMessage(it) }
wait, that does work well if I use a method reference!
after defining…
inline fun <T, reified U : T> ReceiveBuilder<T>.addHandler(noinline handler: (U) -> Behavior<T>): ReceiveBuilder<T> {
    return onMessage(U::class.java, handler)
}
I can do
return new ReceiveBuilder().addHandler(::onMessage)
e

Emil Kantis

11/19/2021, 9:30 PM
great work @Marcus Brito! 🙂