I know this may seem a repeated question but I am puzzled as to how invariance, covariance and contravariance works.
I can't understand why I can't compile this snippet:
class Test<X: List<Any>>{
lateinit var list2:List<Any>
lateinit var list1:X
fun putList(){
list2 = emptyList()
list1 = emptyList<Any>()
}
}
I get the type mismatch error Required X found List
However if I define the X generic as 'out' I will get a error indicating that the parameter X is invariant in list1 var.
Can someone help another poor soul lost in Kotlin generics?
The short answer: The var list1
is covariant, you're trying to use it in a contravariant way.
What you're currently trying to do: Assign an instance of the super type (specified by the upper bound) List<Any>
to a variable of its sub type X
, which is list1
. To simplify the problem, consider the following:
open class Super
class Sub : Super()
val sub: Sub = Super() //Compile Error: Type mismatch: inferred type is Super but Sub was expected
You simply can't assign objects to variables of a sub type of that object. The other way around would be fine though: val sup: Super = Sub()