0% found this document useful (0 votes)
24 views7 pages

14 - Kotlin Generics

14- Kotlin generics

Uploaded by

specsdeveloper13
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views7 pages

14 - Kotlin Generics

14- Kotlin generics

Uploaded by

specsdeveloper13
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Trending Now Data Structures Algorithms Topic-wise Practice Python Machine Learning Data Science J

Kotlin generics
Read Discuss Courses Practice

Generics are the powerful features that allow us to define classes, methods
and properties which are accessible using different data types while keeping a
check on the compile-time type safety. Creating parameterized classes – A
generic type is a class or method that is parameterized over types. We always
use angle brackets <> to specify the type parameter in the program. Generic
class is defined as follows:

class MyClass<T>(text: T) {
var name = text
}

To create an instance of such a class, we need to provide the type of


arguments:

val my : MyClass<String> = Myclass<String>("GeeksforGeeks")

If the parameters can be inferred from the arguments of a constructor, one is


allowed to omit the type arguments:

val my = MyClass("GeeksforGeeks")

Here, GeeksforGeeks has type String, so the compiler figures out that we are
talking about Myclass<String>
Advantages of generic:

1. Type casting is evitable- No need to typecast the object.


2. Type safety- Generic allows only a single type of object at a time.
3. Compile time safety- Generics code is checked at compile time for the
parameterized type so that it avoids run-time error.

Generic use in our program-

In the below example, we create an Company class with a primary constructor


having a single parameter. Now, we try to pass the different types of data in
the object of Company class as String and Integer. The primary constructor of
Company class accepts string type (“GeeksforGeeks”) but gives compile time
error when passes Integer type (12).

Kotlin program without generic class:

Kotlin

class Company (text: String) {


var x = text
init{
println(x)
}
}
fun main(args: Array<String>){
var name: Company = Company("GeeksforGeeks")
var rank: Company = Company(12)// compile time error
}

Output:

Error:(10, 33) Kotlin: The integer literal does not conform to the
expected type String
In order to solve the above problem, we can create a generic type class that is
user defined accepts the different types of parameters in a single class. The
class Company of type is a general type class that accepts both Int and String
types of parameters.

Kotlin program using the generic class:

Kotlin

class Company<T> (text : T){


var x = text
init{
println(x)
}
}
fun main(args: Array<String>){
var name: Company<String> = Company<String>("GeeksforGeeks")
var rank: Company<Int> = Company<Int>(12)
}

Output:

GeeksforGeeks
1234

Variance:

Unlike Java, Kotlin makes arrays invariant by default. By extension, generic


types are invariant in Kotlin. This can be managed by the out and in keywords.
Invariance is the property by which a standard generic function/class already
defined for a particular data type, cannot accept or return another datatype.
Any is the supertype of all other datatypes. Variance is of two types-

1. Declaration-site variance(using in and out)


2. Use-site variance: Type projection

Kotlin out and in Keywords


The out Keyword – In Kotlin, we can use the out keyword on the generic type
which means we can assign this reference to any of its supertypes. The out
value can only produced by the given class but can not consumed:

class OutClass<out T>(val value: T) {


fun get(): T {
return value
}
}

Above, we have defined an OutClass class that can produce a value of type T.
Then, we can assign an instance of the OutClass to the reference that is a
supertype of it:

val out = OutClass("string")


val ref: OutClass<Any> = out

Note: If we have not used the out type in the above class, then given
statement will produce a compiler error.

The in Keyword – If we want to assign it to the reference of its subtype then


we can use the in keyword on the generic type. The in keyword can be used
only on the parameter type that is consumed, not produced:

class InClass<in T> {


fun toString(value: T): String {
return value.toString()
}
}

Here, we have declared a toString() method that only be consuming a value of


type T. Then, we can assign a reference of type Number to the reference of its
subtype – Int:
val inClassObject: InClass<Number> = InClass()
val ref: InClass<Int> = inClassObject

Note: If we have not used the in type in the above class, then the given
statement will produce a compiler error.

Covariance:

Covariance implies substituting subtypes is acceptable, but supertypes is not,


i.e. the generic function/class may accept subtypes of the datatype it is already
defined for, e.g. a generic class defined for Number can accept Int, but a generic
class defined for Int cannot accept Number. This can be implemented in Kotlin
using the out keyword as follows-

Kotlin

fun main(args: Array<String>) {


val x: MyClass<Any> = MyClass<Int>() // Error: Type mismatch
val y: MyClass<out Any> = MyClass<String>() // Works since String is a subtype
val z: MyClass<out String> = MyClass<Any>() // Error since Any is a supertype
}
class MyClass<T>

We can directly allow covariance by appending out keyword to the declaration


site. The following code works just fine.

Kotlin

fun main(args: Array<String>) {


val y: MyClass<Any> = MyClass<String>() // Compiles without error
}
class MyClass<out T>

Contracovariance –
It is used to substitute a supertype value in the subtypes, i.e. the generic
function/class may accept supertypes of the datatype it is already defined for,
e.g. a generic class defined for Number cannot accept Int, but a generic class
defined for Int can accept Number. It is implemented in Kotlin using the in
keyword as follows-

Kotlin

fun main(args: Array<String>) {


var a: Container<Dog> = Container<Animal>() //compiles without error
var b: Container<Animal> = Container<Dog>() //gives compilation error
}
open class Animal
class Dog : Animal()
class Container<in T>

Type projections –

If we want to copy all the elements of an array of some type into the array of
Any type then it can be possible, but to allow the compiler to compile our code
we need to annotate the input parameter with the out keyword. This makes
the compiler to infer that input argument can be of any type that is a subtype
of the Any:

Kotlin program of copying elements of one array into another –

Kotlin

fun copy(from: Array<out Any>, to: Array<Any>) {


assert(from.size == to.size)
// copying (from) array to (to) array
for (i in from.indices)
to[i] = from[i]
// printing elements of array in which copied
for (i in to.indices) {
println(to[i])
}
}
fun main(args :Array<String>) {
val ints: Array<Int> = arrayOf(1, 2, 3)
val any :Array<Any> = Array<Any>(3) { "" }
copy(ints, any)

Output:

1
2
3

Star projections –

When we do not know about the specific type of the value and we just want to
print all the elements of an array then we use star(*) projection.

Kotlin program of using star projections –

Kotlin

// star projection in array


fun printArray(array: Array<*>) {
array.forEach { print(it) }
}
fun main(args :Array<String>) {
val name = arrayOf("Geeks","for","Geeks")
printArray(name)
}

Output:

GeeksforGeeks

Last Updated : 20 Mar, 2023 21

Similar Reads
Android - Create Group Kotlin | Language for
BarChart with Kotlin Android, now Official by
Google

You might also like