Generics in Kotlin
Tags: genericsprogramming, androiddev, generics, kotlin
Published: 2020-08-07 12:51:30

---
title: Generics in Kotlin
published: true
date: 2020-06-21 08:06:39 UTC
tags: genericsprogramming,androiddev,generics,kotlin
canonical_url: https://medium.com/@magdamiu/generics-in-kotlin-5152142e281c
---

Generics means we use a class or an implementation in a very generic manner. For example, the interface List allows us for code reuse. We are able to create a list of Strings, of integer values and we will have the same operations even if we have different types. So the list wraps a common functionality for each implementation.

Kotlin allows you to use parameters for methods and attributes, composing what is known as parameterized classes.

![](https://cdn-images-1.medium.com/max/960/0*lwIr3SMpTNUmEok2)

### 1️⃣Type vs Class vs Subtype

- **Type** describes the properties that a set of objects may share.
- **Class** is just an implementation of that type.
- A **subtype** must accept at least the same range of types as its supertype declares.
- A **subtype** must return at most the same range of types as its supertype declares.

![](https://cdn-images-1.medium.com/max/960/0*cUEPJcxdwwh2D5KC)

### 2️⃣Variance

Variance refers to how subtyping between more complex types relates to subtyping between their components.

Conventions: E = element | T = type | K = key | V = value

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/da23080c2bb542beaa79ea9f0216071e %}

### 3️⃣Covariance

- If C<T> is a generic type with type parameter T and U is a subtype of T, then C<U> is a subtype of C<T>
- Example: List<Int> is a subtype of List<Number> because Int is a subtype of Number.
- Applies to types that are _“producers”_, or a _“source”_ of T
- T only appears only in “out” position, i.e., the return type of a function

![](https://cdn-images-1.medium.com/max/960/0*HVkRnidOFnpUbGby)

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/08842e3d8dfcff4691fc87a6df220f51 %}

### 4️⃣Contravariance

- If C<T> is a generic type with type parameter T and U is a subtype of T, then C<T> is a subtype of C<U>
- U subtype of T ⇒ C<T> subtype of C<U>
- Example: Function1<Number, Int> is a subtype of Function1<Int, Int> because Int is a subtype of Number.
- Applies to types that are _“consumers”_ of T
- T only appears only in _“in”_ position, i.e., the type of a function argument

![](https://cdn-images-1.medium.com/max/960/0*D6DE8s1FECfn8Nv5)

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/41934bb8517b9c2b55a189634d0c3782 %}

### 5️⃣Invariance

- If C<T> is a subtype of C<U>, then T = U
- Example: Array<T> is invariant in T
- T appears in both _“in position”_ and _“out position”_
- Type is both a _producer_ and _consumer_ of T
- To remember: Lambdas are contra-variant in their argument types and covariant in their return type

![](https://cdn-images-1.medium.com/max/960/0*uEfqGAHx_j3dLW2C)

### 6️⃣Type projections

- A type projection is a type that has been limited in certain ways in order to gain variance characteristics using use-site variance.

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/27b0398c15cf3a9350bd4163f8870c16 %}

{% gist https://gist.github.com/magdamiu/4890497a236e5752b47958a96e37cf03 %}

### 7️⃣Star projection

- They come in handy when we know nothing about the type argument, but need to use them in a safe way.
- The safe way here is to define such a projection of the generic type, that every concrete instantiation of that generic type would be a subtype of that projection.
- Instead of using C<in Nothing> or C<out Any?>, you can just use C<\*>. It produces the same effective interface as the other two approaches:
- So then, we have three ways that we can accept any kind of a generic:
- in-projection — <in Nothing>
- out-projection — <out Any?>
- star-projection — <\*>

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/22101a996f41bfbec0385bab505394eb %}

### 8️⃣Type erasure and reified type parameters

- Java has limits on what types are considered _reifiable _— meaning they’re “completely available at run time” (see the [Java SE specs on reifiable types](https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7))
- The type safety checks that Kotlin performs for generic declaration usages are only done at compile time. At runtime, the instances of generic types do not hold any information about their actual type arguments.
- Enforcing type constraints only at compile time and discarding the element type information at runtime.
- The type of information is said to be erased.
- In the case of **reified** type parameters in Kotlin, we can compare types and get Class objects.

**Reified** types parameters:

- Work only with functions (or extension properties that have a get() function)
- Work with those functions that are declared to be inline

Advantages of using reified types parameters:

- type checks with is
- casts without unchecked cast warnings
- assign class objects by appending:class.java to the parameter name. For example: val a = T::class.java

#### 👩🏻‍💻Code sample

{% gist https://gist.github.com/magdamiu/25cb2a91d5ced6169be6bbcf32cc3fd7 %}

### **📚 Learn more**

- Reified type parameters [https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters)
- Generics [https://kotlinlang.org/docs/reference/generics.html](https://kotlinlang.org/docs/reference/generics.html)

Enjoy and feel free to leave a comment if something is not clear or if you have questions. And if you like it please share it!

Thank you for reading! 🙌🙏😍✌

Follow me on:

[https://twitter.com/MagdaMiu](https://twitter.com/MagdaMiu)

_Originally published at_ [_http://magdamiu.com_](https://magdamiu.com/2020/06/21/generics-in-kotlin/) _on June 21, 2020._