Primitive vararg failed to override generic vararg


#1

The following code doesn’t compile and throw
Error Kotlin: Class 'Impl' is not abstract and does not implement abstract member public abstract fun process(vararg index: Int): Unit defined in Processor.

interface Processor<T> {
    fun process(vararg index: T): Unit
}

class Impl : Processor<Int>{
    override fun process(vararg index: Int) {
        TODO("not implemented")
    }
}

But the following code compiles.

interface Processor<T> {
    fun process(vararg index: T): Unit
}

class Impl : Processor<Number>{
    override fun process(vararg index: Number) {
        TODO("not implemented")
    }
}

Why and how to deal with it?


#2

Using Kotlin Bytecode, Processor's process funciton becomes Object...var1 while Impl becomes int...var1.
I know this is the cause. The question is how to avoid this? (In Java we can use Integer, In kotlin, we can only use Int.)


#3

according to Force / hint of Int to java.lang.Integer?, maybe we can use java.lang.Integer to solve this problem.
But this will result in other problems about Integer and Int.
In my example, the usage of Processor will be like process(Integer(1),Integer(2)) instead of process(1,1).


#4

Another solution maybe using Int? to force boxed Int? This way will introduce null safety things.


#5

This looks like compiler bug. Compiler should use java.lang.Integer in this case. Using Int? looks like the best workaround.


#6

I don’t know whether this a compiler bug or just an inevitable consequence of the type system but I agree with @vbezhenar that the best solution is to use Int? rather than Int.

The null-checking aspects will be confined to your override of the process method as the method is not returning anything. Also you’ll be able to pass integer arguments ‘naturally’ instead of wrapping them in Integer objects.

Another problem with Integer is that the compiler doesn’t like you using it and will issue warnings if you do.