Confusion with Kotlin generics

I am new to Kotlin and I am trying to write code that does something pretty simple, however I cannot figure out how to use generics to get it to work.

I have a trait Handler

that is a handler for things. I cannot change the code for the handler as it comes from the library .

trait Handler<T> {
    fun handle(result: T)


All the codes below are under my control -


- Open a class that has subclasses such as AdminUser

and GuestUser


The AdminUserAction

trait that creates the AdminUsers list then passes the list to the handler for List<AdminUser>


trait AdminUserAction {
    fun then(handler: Handler<List<AdminUser>>)


Now I want to pass a AdminUserAction

handler for User

instead of AdminUser

. Let's say the handler just registers the usernames and does nothing with the specific admin properties.

fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) {


However, this code gives me a TypeMismatch.

Since the handler is of type List<T>

and immutable, the previous code should be completely safe, however the compiler cannot understand it.

If I had access to the code for the Handler, I could do the following and it would work -

trait Handler<in T> {
    fun handle(result: T)


However, as I said before, I cannot modify the Handler as it comes from the library. Also, it seems like a hack to do this because the handler type is completely generic and should be used for other kinds of handlers as well.

I tried the subclass handler and used it -

trait ListHandler<in T>: Handler<List<T>> { }


However, now I am getting an error: "Parameter T is declared as" in ", but occurs at an" invariant "position in Handler>"

I tried -

trait ListHandler<in T>: Handler<List<in T>> { }


But this is giving me more errors.

Why is this so confusing? And how can I use generics to make the previous code work?


I can get it to work by writing a generic function that converts a Handler<List<User>>

to Handler<List<AdminUser>>


fun <T: User> fromGeneric(handler: Handler<User>): Handler<T> {
    return object: Handler<T> {
        override fun handle(result: List<T>) {


And then -

fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) {


But it seems so wasteful. Look especially at the body of the transform function fromGeneric

. He does nothing ! However, I have to go through rigamarole using it every time to satisfy the types.

Is there a better way? Is it technically possible to make the Kotlin compiler smarter so that this type of focus isn't needed?


source to share

1 answer

There are several solutions:

Change the definition AdminUserAction


trait AdminUserAction {
    fun then(handler: Handler<in List<AdminUser>>)


or change the definition AdminUserAction


trait AdminUserAction {
    fun then(handler: Handler<List<User>>)


or just enter printAllNames

like this

fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) {
    action.then(printAllNames as Handler<List<AdminUser>>)




All Articles