out Is a Direction

out indicates that our dominant use of the generic type is to return values of that type. And, as such, we believe that it is safe for us to support sub-types of that type.

Remember that in Kotlin (and many strongly-typed object-oriented programming languages) a variable or property type need only be compatible with its value’s actual type. Objects have type — a variable or property’s type says “we are using this object as if it its type were X”, regardless of the actual type of that object.

So, suppose that MutableList allowed subtypes and this statement succeeded:

val animals: MutableList<Animal> = mutableListOf<Frog>(Frog(), Frog())

animals says “I hold a list of Animal objects”, and it allows you to assign any Animal to any index. So, from a compilation standpoint, this would work:

animals[0] = Axolotl()

After all, Axolotl is an Animal.

However, while animals says “I hold a list of Animal objects”, the actual object that animals points to says “I hold a list of Frog objects”. We cannot put an Axolotl in a List<Frog>, and so animals[0] = Axolotl() would cause one of two problems:

  1. It would fail immediately, on the grounds that you cannot put an Axolotl in a List<Frog>
  2. It would fail when we later try retrieving that element, because Kotlin would try treating an Axolotl as if it were a Frog, and that would result in a ClassCastException or similar problem

So, MutableList is invariant in its generic type. A MutableList<Frog> needs to be based on a list of Frog objects, and if we have a MutableList<Animal> variable or property, the actual underlying list needs to support any type of Animal, not just one sub-type.

But List does not support mutation. If you review the functions on List, either:

In other words, for the operations that List performs, it does not matter if the underlying list is of a sub-type or not. All the List operations still work.

That is why List can use out to say that it is covariant in the generic type. A List<Animal> variable or property can point to a List<Frog> without issue, because at no point will we be forced to try to put an Axolotl into that List.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.