9/19/24, 8:00 PM Kotlin Generics - in, out, where.
In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
Open in app Sign up Sign in
Search Write
Kotlin Generics - in, out, where
Manuchekhr Tursunov · Follow
4 min read · Apr 22, 2023
224 1
In Kotlin, generics provide the ability to create classes, interfaces, and
methods that can work with various types, without specifying the actual type
until the object is created.
In
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 1/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
The <in> keyword in generics is used to specify a type parameter as a
contravariant. Contravariant means that the type can be used as input
parameters.
Here’s an example of using <in> with generics in Kotlin:
interface AnimalCare<in T> {
fun takeCareOf(animal: T)
}
class Vet : AnimalCare<Animal> {
override fun takeCareOf(animal: Animal) {
// do something
}
}
class Animal {}
class Dog : Animal {}
fun main() {
val animalCare: AnimalCare<Dog> = Vet()
animalCare.takeCareOf(Dog())
}
In the above example, AnimalCare is a generic interface with the type
parameter T marked as in . The Vet class implements the AnimalCare
interface with the type parameter Animal . The main function creates an
instance of AnimalCare with the type parameter Dog , but assigns it to a
variable of type AnimalCare<Animal> . Since Dog is a subtype of Animal , it can
be passed to the takeCareOf method of the Vet class.
Using the <in> keyword in generics allows for a greater degree of flexibility
in using classes, interfaces, and methods with different types. It is especially
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 2/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
useful when dealing with classes that accept input parameters, such as with
the takeCareOf method in the above example.
Out
In Kotlin, the <out> keyword is used to define covariance in generic classes
and interfaces. It allows for a more flexible use of generics, allowing a
subtype of a generic type to be used in place of the parent type.
When a generic class or interface is defined with the <out> keyword, it
means that the type parameter can only appear in the output positions of
member functions. This means that it can only be returned from functions
or used as a property type.
Here’s an example of a generic interface using the <out> keyword:
interface Producer<out T> {
fun produce(): T
}
In this example, T is a covariant type parameter. This interface has a single
function produce() that returns an object of type T. Since T is covariant, the
produce() function can return a subtype of T.
Here’s an example of how this interface can be used:
class FruitProducer : Producer<Fruit> {
override fun produce(): Fruit {
return Apple()
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 3/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
}
}
In this example, Fruit is the type parameter for Producer . The
FruitProducer class implements the Producer interface and overrides the
produce() function to return an object of type Fruit , which in this case is an
instance of Apple . Since T is covariant, FruitProducer is allowed to return an
Apple object instead of a Fruit object.
Using the <out> keyword in generics can make your code more flexible and
reusable. It allows you to use subtypes of a generic type where the parent
type is expected, making your code more adaptable to changes in the future.
Where
The where keyword in Kotlin is used to add constraints on the types used as
generic type parameters. It allows you to specify that a generic type
parameter must be a subtype of a specific class or implement a specific
interface.
Here’s an example of using where to add constraints on a generic function:
fun <T> addNumbers(a: T, b: T) where T : Number {
val result = a.toDouble() + b.toDouble()
println("Result: $result")
}
In the above example, we’ve added a constraint on the generic type
parameter T using the where keyword. The constraint specifies that T must
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 4/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
be a subtype of the Number class.
Now, let’s see how we can use this function:
addNumbers(3, 5) // Output: Result: 8.0
addNumbers(2.5, 4.5) // Output: Result: 7.0
addNumbers("hello", "world") // Compilation error: Type parameter bound for 'T'
As you can see, the function can only be called with arguments that are
subtypes of Number .
You can also use the where keyword to add multiple constraints on a generic
type parameter. Here's an example:
fun <T> processList(list: List<T>) where T : CharSequence, T : Comparable<T> {
val sortedList = list.sorted()
sortedList.forEach { println(it) }
}
In the above example, we’ve added two constraints on the generic type
parameter T using the where keyword. The constraints specify that T must
be a subtype of the CharSequence class and must also implement the
Comparable interface.
Now, let’s see how we can use this function:
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 5/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
val stringList = listOf("apple", "banana", "orange")
processList(stringList) // Output: apple banana orange
val intList = listOf(3, 2, 1)
processList(intList) // Compilation error: Type parameter bound for 'T' is not s
As you can see, the function can only be called with arguments that are
subtypes of CharSequence and implement the Comparable interface.
In summary, the where keyword in Kotlin allows you to add constraints on
generic type parameters to restrict the types that can be used as arguments
for generic functions or classes.
Kotlin Generics Coding Software Development Development
Written by Manuchekhr Tursunov Follow
448 Followers
I am passionate Android Developer. Suppor me: https://ko-fi.com/manuchekhrdev Twitter:
https://twitter.com/manuchekhrdev. Github: https://github.com/ManuchekhrT
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 6/10
9/19/24, 8:00 PM Kotlin Generics - in, out, where. In Kotlin, generics provide the ability… | by Manuchekhr Tursunov | Medium
More from Manuchekhr Tursunov
Manuchekhr Tursunov Manuchekhr Tursunov
Access token expiration. Refresh Sealed Class vs Sealed Interface in
Token. Retrofit Interceptor,… Kotlin
I will bring an example of implementation in Sealed class and Sealed interface are two
Kotlin for handling token expiration and… features in Kotlin that allow the creation of…
May 25, 2023 302 3 Apr 28, 2023 175 4
https://medium.com/@manuchekhrdev/kotlin-generics-in-out-where-9181ddbef01f#:~:text=In Kotlin%2C generics provide the ability to create classes… 7/10