Array of inherited types (and other generic classes...)


#1

Suppose that type A inherits type B or implements interface B.
Now suppose that I define a function

fun f(myArgument: Array<B>)

somewhere else I declare some variable myArray of type Array<A>.
Now a direct call

f(myArray) 

causes a compilation error.

  1. What is the reason for this? I think it is acceptable Java code.
  2. What is the workaround if I want to translate the equivalent Java code into Kotlin code? (Auto-translate results in code that can not compile). Using
    f(myArray as Array<B>)
    solved the problem in the few cases I’ve tried, but is it always guaranteed to work?

Thanks.

PS: Sorry if I am missing something trivial - Java/Kotlin noob here.


#2

Arrays are invariant of Kotlin. It means that you can’t an Array<A> is not a subtype (and not a supertype) of an Array<B> even if A is subtype of B, so you can’t pass an Array<A> where Array<B> is expected.

And there’s a reason for that — consider your f function can try to write values of type B to an Array<B> — it would fail if an Array<A> is passed instead.

However if you only want to read B values from an array, you can declare it as Array<out B> — a covariant projection. Then Array<A> is a subtype of Array<out B> if A is subtype of B.
You can read more about variance in the docs: https://kotlinlang.org/docs/reference/generics.html#variance