# Generic variance: can't use var with \<out T\> and can't use val with \<in T\>?

**URL:** <https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868>\
**Category:** Support\
**Created:** [August 22, 2020, 12:48am UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868 "2020-08-22T00:48:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 22, 2020, 12:48am UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/1 "2020-08-22T00:48:26Z")

</div>

So, I vaguely understand that a generic class declared with an “out” is a “producer” and if declared with an “in”, it is a “consumer”.

All in all, what I understand from this is that functions declared within the generic class can only either produce a result of type T (out), or take in as an argument a type T (in), but not both.

I also suppose this means that an “out” generic class is read-only, while an “in” generic class is write-only.

Why though are there restrictions on a property of type T?  
Upon declaring a generic class of type \<out T\>, any vars of type T are marked as inappropriate. This, I can kind of understand, as “out” generics are “read-only”, and therefore wouldn’t support a var which could allow re-assigning or re-writing to the var variable.

But why can’t I use a val in a generic of \<in T\>? I don’t feel like I am producing anything when I have a val of type T.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 22, 2020, 8:58am UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/2 "2020-08-22T08:58:59Z")

</div>

A generic class that has an type parameter can be down casted to any lower class. This is because it is a consumer, as in it only takes in values of type T. The reason why you can’t do that is because say for example that you have a `class Container<in T>` with a val property of type T.  
Because this container is a consumer (i.e it’s type parameter is declared with an `in`), then you can for example safely cast a `Container<Any>` into a `Container<String>` because Container is supposed to be able to consume any object of type `Any`, which means that because `String` inherits from Any (i.e. String’s superclass is Any), that same Container should be able to accept values of String, too. But now if you can safely cast a `Container<Any>` to a `Container<String>`, and you have a val property that you try to access, that val property was beforehand allowed to be of type Any, but now you are trying to cast it to a String, so boom `ClassCastException`.

Here’s a minimal example that shows that with those same classes:

```auto
class Container<in T>(val content: T) //Compiler error right here

fun main() {
    val cont = Container<Any>(Any()) // Just creating a new Any object for this example
    val contString: Container<String> = cont //This is totally legal because in guarantees downcasting safely
    val str: String = contString.content //Whoops, you are now trying to cast an Any to a String.
}

```

Rule of thumb is that `in` consumers guarantee safe downcasting (i.e. from an Any to a String for example), while `out` producers guarantee safe upcasting (i.e. from a String to an Any because if some other part of your program expects a producer to give them an Any and it gives them a String then that’s totally fine, but the opposite isn’t).

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 22, 2020, 10:43pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/3 "2020-08-22T22:43:40Z")

</div>

Thanks again for the reply @kyay10.  
I’m not quite sure I’m following though. From what I understand, \<in T\> sets up a contravariant situation, allowing you to safely cast a `Container<String>` into a `Container<Any>`. I feel like you might be describing a covariant situation, but honestly, I’m not good at this. That being said, the code you provided does indeed seem to be casting a `Container<String>` into a `Container<Any>`.

Also, I think there are some portions of your text not showing up. I’ve noticed that when using angle brackets ( ‘\<’ and ‘\>’), as in typing Container\<String\>, you have to use the the backslash escape character '\ 'before the ‘\>’ or it doesn’t show up, like so: `Container<String\>`. For example, the following is supposed to say “Container\<String\> = Container\<Any\>” but I have left out the escape character:  
Container = Container.  
This goes away when marking it as code text of course. Anyway, areas that you might have typed \<String\> or \<Any\> are missing in your text so I have a hard time following.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 22, 2020, 11:36pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/4 "2020-08-22T23:36:18Z")

</div>

whoops, I’m sorry. It looks fine on my end for some reason. Regardless, cont is a Container of Any, contString is a Container of String, which gets assigned to cont (because `in` means that we can safely downcast, i.e. take a Container of Any and cast it to a Container of Int or String or whatever our heart desires because `in` allows the class to only consume those values, and so if a class can consume parameters of type Any, it can also consume parameters of type String or Int. The opposite is not true tho, because casting a Container of String to a Container of Any is problematic cuz it imples that the functions on Container that accept a String now suddenly can also accept an Any. `out`, on the other hand, means that we only produce/expose values to the outside world, so it is fine if we are exposing Strings for example and someone upcasts that class as producing Anys, because all Strings are Anys)

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 22, 2020, 11:39pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/5 "2020-08-22T23:39:04Z")

</div>

My bad, your code is fine. I can read that perfectly. It’s in the text above the code where stuff went missing, for example, when you typed “But now if you can safely cast a Container to a Container”, I’m assuming it was supposed to say Container\<String\> to a Container\<Any\> or something similar.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 22, 2020, 11:39pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/6 "2020-08-22T23:39:54Z")

</div>

> [@Mervil](#):
>
> . From what I understand, sets up a contravariant situation, allowing you to safely cast a `Container<String>` into a `Container<Any>`

contravariant situations allow you to safely downcast a Container of Any to a Container of String, basically limiting what that container accepts as input values, which is fine because every String is an Any

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 22, 2020, 11:40pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/7 "2020-08-22T23:40:19Z")

</div>

> [@Mervil](#):
>
> But now if you can safely cast a Container to a Container”

Oh, that also looks wrong on my screen, my bad. I’ll fix it rn!

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 22, 2020, 11:45pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/8 "2020-08-22T23:45:29Z")

</div>

Also, the [Kotlin documentation](https://kotlinlang.org/docs/reference/generics.html) describe the whole covariant vs contravariant thing probably more elegantly than I ever could:

> The general rule is: when a type parameter `T` of a class `C` is declared **out** , it may occur only in **out** -position in the members of `C` , but in return `C<Base>` can safely be a supertype of `C<Derived>` .
> 
> In “clever words” they say that the class `C` is **covariant** in the parameter `T` , or that `T` is a **covariant** type parameter. You can think of `C` as being a **producer** of `T` 's, and NOT a **consumer** of `T` 's.
> 
> In addition to **out** , Kotlin provides a complementary variance annotation: **in**. It makes a type parameter **contravariant** : it can only be consumed and never produced. A good example of a contravariant type is `Comparable` :

They also include this code example, which might make things clearer:

```auto
interface Comparable<in T> {
    operator fun compareTo(other: T): Int
}

fun demo(x: Comparable<Number>) {
    x.compareTo(1.0) // 1.0 has type Double, which is a subtype of Number
    // Thus, we can assign x to a variable of type Comparable<Double>
    val y: Comparable<Double> = x // OK!
}

```

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 22, 2020, 11:46pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/9 "2020-08-22T23:46:29Z")

</div>

I might be misunderstanding what “cast into” means. Can “cast into” mean the same thing as “inherits from”?

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 23, 2020, 12:02am UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/10 "2020-08-23T00:02:10Z")

</div>

Sort of. Variance basically adds a new layer on top of regular inheritance which says whether or not we care about what we are getting in or what we are pushing out in relation to that type. In simpler terms, a `Producer<out T>` has this “inheritance” relationship:

```auto
           Producer<Any>
                ^^
               / \
              / \
Producer<Number> Producer<String>
        ^ 
        |
Producer<Int>

```

where an arrow points to what this value can be safely cast as (i.e. an arrow from `Producer<Int>` to `Producer<Number>` means that a `Producer<Int>` can be safely cast as an `Producer<Number>` (i.e. you can use a `Producer<Int>` whenever you need a `Producer<Number>` with no bad effects. Same way as you can use a String as an Any or an Int as a Number with no bad effects). On the other hand, a `Consumer<in T>` has this inheritance relationship:

```auto
Consumer<Int>
        ^
        |
Consumer<Number> Consumer<String>
            ^ ^
             \ /
              \ /
           Consumer<Any>

```

As you can see, `in` vs `out` basically flips the whole tree. It all just depends on whether or not you are exposing something that could potentially not follow the type without the compiler screaming in your face. Generics are mostly just used as a way to alert the user to potential bugs at compile time. Another really notable example of this is Kotlin’s `List<out T>`, which allows you to use a List of Ints as a List of Anys.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [August 23, 2020, 10:16am UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/11 "2020-08-23T10:16:45Z")

</div>

> [@kyay10](#):
>
> contravariant situations allow you to safely downcast a Container of Any to a Container of String

That’s correct. But calling it down-casting can sound counter-intuitive without understanding that `Consumer<Any>` is indeed a subtype of `Consumer<String>`, thanks to its contra variant type parameter. Hence the former can safely be cast into the later (without ever producing a runtime error).

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 23, 2020, 1:40pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/12 "2020-08-23T13:40:49Z")

</div>

Yeah I see what you mean. I should’ve clarified that I meant downcasting as in downcasting the type parameter itself. Thanks for the tip!!

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 24, 2020, 2:45pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/13 "2020-08-24T14:45:54Z")

</div>

I have started to understand these covariant and contravariant relationships a bit better with continued online reading. Especially after reading these “guides”:

> **[An Illustrated Guide to Covariance and Contravariance in Kotlin](https://typealias.com/guides/illustrated-guide-covariance-contravariance/)**
>
> Confused about generic subtyping? With just a few simple, foundational concepts, almost everything about variance becomes clear. If you're confused about how subtyping works with generics in Kotlin, start here.

> **[The Ins and Outs of Generic Variance in Kotlin](https://typealias.com/guides/ins-and-outs-of-generic-variance/)**
>
> The ultimate guide to understanding generics, covariance, contravariance, and type projections in Kotlin. Learn two simple subtyping rules that explain why generic variance works the way that it does.

These guides illustrate the type/subtype relationship with variance. However, they don’t give real life code examples other than use of functions defined in the generic class, so I’m not certain how one would utilize these type/subtype relationships in code otherwise. Would that be done via casting?

You mention “downcasting” and “casting” and I’m now trying to take the type/subtype relationships I am understanding and apply them to casting, but I’m not getting there.

In the code example you provided above:

> ```
> class Container<in T>(val content: T) //Compiler error right here
> 
> fun main() {
> val cont = Container<Any>(Any()) // Just creating a new Any object for this example
> val contString: Container<String> = cont //This is totally legal because in guarantees downcasting safely
> val str: String = contString.content //Whoops, you are now trying to cast an Any to a String.
> }
> 
> ```

We have setup a simple generic class. We can create objects of that class with an Any type or a String type, or any other type.  
We create an object of type `Container<Any>`, and reference it with the val `cont`.  
It looks like we then cast that object as a type `Container<String>` and reference that with a different val `contString`. Is there a type/subtype relationship here?

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 24, 2020, 4:41pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/14 "2020-08-24T16:41:08Z")

</div>

Yes. `Container<Any>` is a subtype of `Container<String>`. It’s basically a flipped hierarchy in relations to the type parameter (i.e. `Any` for example is not a subtype of anything, while `String` is just a subtype of `Any`, but when you have a **Container** of `Any`, then it is a subtype of every **Container**. This is because Container has an `in` type parameter. If you have a different clas tho (called Producer for example) that has an `out` type parameter, then a **Producer** of `String` is a subtype of a **Producer** of `Any` i.e the hierarchy is quite similar to the normal type hierarchy)

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 24, 2020, 4:44pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/15 "2020-08-24T16:44:28Z")

</div>

That’s one definition that keeps coming up that I can’t wrap my head around. I simply cannot see how a `Container<Any>` can be a subtype of `Container<String>`. To me that’s like saying a vegetable is a subtype of a carrot, or the solar system is a subtype of Earth.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 24, 2020, 4:50pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/16 "2020-08-24T16:50:21Z")

</div>

I know what you mean lol. It’s kinda weird, but think of it as describing the input. If a class (which is called Consumer for the sake of simplicity) can accept all values of type `Number`, then it can also accept values of type `Int`, and so a `Consumer<Number>` can be cast to a `Consumer<Int>` safely, because the only thing that that Consumer will do with the type is just take it in. Safely casting is synonymous with subtyping i.e. if you can safely cast a B to an A, then B is a subtype of A.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [August 24, 2020, 4:51pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/17 "2020-08-24T16:51:45Z")

</div>

The truth of the matter is that Generics are just a compile-time guarantee. At runtime on the JVM, they are all erased. They just serve as a tool to prevent the programmer from making stupid mistakes like trying to access a `List<Any>` as a `List<String>`

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 24, 2020, 5:22pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/18 "2020-08-24T17:22:04Z")

</div>

I think I understand this “safe casting” now:  
a `Consumer<Number>` can safely be cast to a `Consumer<Int>` because even though the `Consumer<Number>` can accept more types than just Int, only the Int will be utilized in this case, so it is safe to use a `Consumer<Number>` as a `Consumer<Int>`.

> [@kyay10](#):
>
> ```auto
> class Container<in T>(val content: T) //Compiler error right here
> 
> fun main() {
> val cont = Container<Any>(Any()) // Just creating a new Any object for this example
> val contString: Container<String> = cont //This is totally legal because in guarantees downcasting safely
> val str: String = contString.content //Whoops, you are now trying to cast an Any to a String.
> }
> 
> ```

So, in the above code, we are casting `cont` as a `Container<String>` into `contString`, right?

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [August 24, 2020, 5:58pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/19 "2020-08-24T17:58:06Z")

</div>

> [@Mervil](#):
>
> To me that’s like saying a vegetable is a subtype of a carrot

But that’s not what we are saying. We are saying that carrot is a subtype of vegetable and therefore a vegetable consumer is a subtype of a carrot consumer.

---

<div class="post-metadata">

**Author:** ![Mervil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mervil/32/7785_2.png) [@Mervil](https://discuss.kotlinlang.org/u/Mervil)\
**Post date:** [August 25, 2020, 11:06pm UTC](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868/20 "2020-08-25T23:06:44Z")

</div>

I think I’ve confused myself again. I know I’m thinking about this too hard.

```
class Container<in T>(val content: T) //Compiler error right here

fun main() {
    val cont = Container<Any>(Any()) // Just creating a new Any object for this example
    val contString: Container<String> = cont //This is totally legal because in guarantees downcasting safely
    val str: String = contString.content //Whoops, you are now trying to cast an Any to a String.
}

```

I understand, in this example, the `<in>` and contravariant relationship. I’m not understanding what the end result of the “casting” is though. We define an object of type `Container<Any>` and we reference it with a `val` called `cont`.  
`cont` has a property called `content`.  
`cont.content` equals `Any()` and would be of `Any` type.

Now, we establish a new `val` called `contString` and we reference the same `Container<Any>` object as `cont`, but we are… what? … limiting that reference to a type of `Container<String>`? Like looking at the object through a narrowed window? Does this change `<T>` at all from `<Any>` to `<String>`, so that the `content` property for `contString` would of type `String` now, instead of `Any`?  
More specifically, are `cont` and `contString` still referencing the same object, or is `contString` referencing a different object that was redefined as a `String` type using the `Container<Any>` object as a template?

[Next page](https://discuss.kotlinlang.org/t/generic-variance-cant-use-var-with-out-t-and-cant-use-val-with-in-t/18868.md?page=2)
