Kotlin Generics With Examples

In this tutorial, we’ll be looking in Kotlin Generics and Variances.

Generics

Generics are a powerful feature that allows us to define a common class/method/property that can be operated using different types while keeping a check of the compile-time type safety.
They are commonly used in Collections.
A generic type is a class or interface that is parameterized over types. We use angle brackets (<>) to specify the type parameter. To understand Generics, we need to understand types.
Every class has a type which is generally the same as the class.
Though, in Kotlin a nullable type such as String? won’t be considered a class type.
Same goes for a List<String> etc.

An example of Kotlin Generic classes is given below:

We’ve instantiated the class using explicit types as well as allowing the compiler to infer them.

Variance

Variance is all about substituting a type with subtypes or supertypes.
The following thing works in Java:

This means Arrays in Java are covariant.

Convariant means, substituting:
Subtypes are acceptable.
Supertypes are not.

So using the covariant principle the following Java code works as well:

The Number class is the parent of Integer class hence the inheritance and subtyping principle works above.
But the above assignment is risky if we do something like this:

This would lead to a runtime exception in Java since we cannot store a Double as an Int.

Kotlin Arrays stays away from this principle by making arrays invariant by default.

Invariant means, substituting:
Subtypes are not allowed.
Supertypes are not allowed.

So the above runtime error won’t occur with Kotlin Arrays.

Hence, one of the major differences in variances between Kotlin and Java is:

Kotlin Arrays are invariant. Java Arrays are covariant.

Applying the above concepts DON’T COMPILE when used with Generics and Collections for both Java and Kotlin.

By default, the Generic types are invariant. In Java, we use wildcard characters to use the different type of variances.
There are two major types of variances besides invariant.

Covariant

A ? extends Object is a wildcard argument which makes the type as covariant.
Our previous java code now works fine.

The third statement is an example of Covariance using wild card arguments.

The modifier out is used for applying covariance in Kotlin.

In Kotlin, we can directly annotate the wildcard argument on the parameter type of the class. This is known as declaration-site variance.

The above Kotlin code looks more readable than the Java one.

To sum up Covariance in Kotlin:
Use out
Used to set substitute subtypes. Not the other way round

Contraconvariant

This is just the opposite of Covariance. It’s used to substitute a supertype value in the subtypes.
It cannot work the other way round.
It uses the in modifier

Kotlin in is equivalent to <? super T> of Java.
Kotlin out is equivalent to <? extends T> of Java.

This brings an end to this tutorial on Kotlin Generics and Variance.

By admin

Leave a Reply

%d bloggers like this: