javakotlingenericswildcard

Meaning of words "in" and "out" in Kotlin generics


I learn kotlin generics but naming makes me crazy.

Let consider 2 code snippets in java and in Kotlin which do the same job:

1. java

    public void copy(List<? extends Number> from, List<? super Number> to) {
        assert from.size() == to.size();
        for (int i = 0; i < from.size(); ++i) {
            to.add(from.get(i));
        }
    }

Everything is clear.

from is a list of items of type which inherits from Number. So it could be List<Double> List <Short> etc. I understand why extends word is used

to is a list of items of type which is a supertype of Number. So it could List<Number> or List<Serializable> or List<Object>

2.Kotlin

The similar code for Kotlin:

    fun copy(from: Array<out Number>, to: Array<in Number>) {
        assert(from.size == to.size)
        for (i in from.indices)
            to[i] = from[i]
    }

From my point of view it looks counterintuitive. Why Array<out Number> is Array of subtypes of Number ?

Why Array<in Number> is Array of supertypes of Number ?

I am sure creaters had some logic and I want to understand it.


Solution

  • Array<out Number> is an array you can get Numbers out of.

    Array<in Number> is an array you can put Numbers in to.

    This is the core of how you should be thinking about it, and specifically why those names make sense. For what exactly the relevant types are -- when you think about "what sort of array can I get Numbers out of, you will notice that you can certainly get Numbers out of an Array<Int> or an Array<Double>, and conclude that any type that extends Number is a valid type argument for Array<out Number>. Additionally, you can certainly put any Number into an Array<Object>, and deduce that an Array<in Number> is an Array<T> where T is some supertype of Number.

    In general, however, Kotlin just switches from "what could this type be?" which List<? extends Number> makes clearer, to "what can I do with this type?" which MutableList<in Number> makes clearer.