Reified : Kotlin
--
Before we learn about reified,
Generics in any language is the powerful features that allow us to define classes, methods and properties which are accessible using different data types while keeping a check of the compile-time type safety.
This post was originally posted at https://agrawalsuneet.github.io/blogs/reified-kotlin/ and reposted on Medium on 8th Mar 2021.
The best example for generics is Array or any List/Collection implementation.
package kotlin
/**
* Represents an array (specifically, a Java array when targeting the JVM platform).
* Array instances can be created using the [arrayOf], [arrayOfNulls] and [emptyArray]
* standard library functions.
* See [Kotlin language documentation](https://kotlinlang.org/docs/reference/basic-types.html#arrays)
* for more information on arrays.
*/
public class Array<T> {
/**
* Creates a new array with the specified [size], where each element is calculated by calling the specified
* [init] function.
*
* The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index.
*/
public inline constructor(size: Int, init: (Int) -> T)
/**
* Returns the array element at the specified [index]. This method can be called using the
* index operator.
* ```
* value = arr[index]
* ```
*
* If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS
* where the behavior is unspecified.
*/
public operator fun get(index: Int): T
/**
* Sets the array element at the specified [index] to the specified [value]. This method can
* be called using the index operator.
* ```
* arr[index] = value
* ```
*
* If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS
* where the behavior is unspecified.
*/
public operator fun set(index: Int, value: T): Unit
/**
* Returns the number of elements in the array.
*/
public val size: Int
/**
* Creates an iterator for iterating over the elements of the array.
*/
public operator fun iterator(): Iterator<T>
}
Here the templete T
can be of any class that the reason we can create an Array
or List
of any class objects.
Now, let’s try to get the type of this template at run time within the function.
fun <T> Array<T>.average() : Float {
print("${T::class.java}") //Compilation Error
//return default value
return 0.0f
}
What we are trying to achieve here is we want to add an extension function to Array which will check the type at run time and if that type is Int, it will return the average of all the elements in that array else this will return 0.0f
This will give the below compilation error
Cannot use 'T' as reified type parameter. Use a class instead.
The possible way to access the type of the Template class is by passing it as a parameter.
Since we can not use the type of template at runtime directly, we need to use reified here.