Error Override by a function with reified type parameter


#1

I have created following lnterface

interface MsgInterface{
  fun<M> Send(msg: M)
}

class MsgProcessor : MsgInterfce {
    override inline fun<reified M> Send(msg:M){
    //Process send message
   }
 }

I am getting following error message while compiling

"Override by a function with reified type parameter"

How to solve this issue?


#2

The problem is that it’s impossible to inline virtual members. This can be shown in a small example.

interface MsgInterface {
   inline <M>fun send(msg: M)   // this is not allowed, but let's pretend
}

class A: MsgInterface { ... }
class B: MsgInterface { ... }

val msg = listOf(A(), B())
msg.forEach{
    it.send()   // even though send is "inline" it can't be because the compiler does not know which "send" to use
}

What you can do is this

interface Foo {
    fun foo()
}
class A: Foo {
    override inline fun foo() {}
}

This will only generate a warning. If you call someA.foo() the compiler can inline it. If you however call (someA as Foo).foo() the compiler can’t because of what I showed above.

The problem you have is that you try to use reified. Reified is a special keyword that allows kotlin to get around a restriction on the JVM. The problem on the JVM is that you only know the type of generics at compile time and not at runtime. That’s why you can’t normally use T::class. Reified works by inlining the function therefor removing this restriction. The problem is now that you can’t inline (someA as Foo).foo().

This depends on what you are trying to achieve. You have to change your code so it does not rely on reified to work.


#3

Hi Wasabi,

I have to use `M::class` on inside the send method. so i have used `<reified M>` keyword  

Is it not possible to avoid the error “Override by a function with reified type parameter”?


#4

No. As I explained you can not use reified for virtual(orverride/open) functions. What you could do is change your interface to this

interface MsgInterface {
    fun <M> Send(msg: M, klass: KClass<M>)
}

That way you don’t need to use M::class inside of your function but can use klass instead. It’s the way this is often done in plain java. It’s not as nice as reified but it works.