I recently study about kotlin Generics, But i found some weird stituation
interface MyItem
fun <ITEM : MyItem> bindItem(items: List<ITEM>?) {
val castedItem = items as List<MyItem>?
}
fun <ITEM : MyItem> bindItem2(items: MutableList<ITEM>?) {
val castedItem = items as MutableList<MyItem>?
}
Only In MutableList case compiler warn about unchecked Cast
If anyone knows about this situation, Please tell me about this.
The
Listinterface has declaration site covariance (<out T>). This means it is safe to "upcast" the type because a List only ever outputs items. For example, if you have aList<Int>, it is safe to use it as aList<Number>because anIntcan always be safely cast to aNumber. When you retrieve items from the list, they always satisfy being the typeIntor the supertypeNumber.MutableListdoes not have a covariant type. It is invariant at the declaration site. This means it is not inherently safe to "upcast" its type. For example, if you cast yourMutableList<Int>to aMutableList<Number>, it is not safe to use theMutableList<Number>reference, because it would let you add aFloatto the list. When the original reference is used as aMutableList<Int>and tries to retrieve a value from it, it will get a ClassCastException for trying to use theFloatas anInt.In this case, you could safely cast the
MutableListto a covariant type, like this:but a
MutableListwith a covariant type is not really any different than aList(except that you canclear()it), so it would be better to cast it to aList<MyItem>to make the intent clearer.