How do I get the general param class in Kotlin?

I need to tell the general type of kotlin collection at runtime. How can i do this?

val list1 = listOf("my", "list")
val list2 = listOf(1, 2, 3)
val list3 = listOf<Double>()

/* ... */

when(list.genericType()) {
    is String -> handleString(list)
    is Int -> handleInt(list)
    is Double -> handleDouble(list)
}

      

+3


source to share


2 answers


Kotlin generators share Java's compile-time erasure characteristic, so at runtime these lists no longer contain the information you need to do what you ask. The exception is that you are writing a built-in function using reified types. For example, this would work:

inline fun <reified T> handleList(l: List<T>) {
    when (T::class) {
        Int::class -> handleInt(l)
        Double::class -> handleDouble(l)
        String::class -> handleString(l)
    }
}

fun main() {
    handleList(mutableListOf(1,2,3))
}

      

Built-in functions extend at every calling site, albeit a mess with your stack traces, so you should use them sparingly.



There are some alternatives depending on what you are trying to achieve. You can achieve something like this at the element level with private classes:

sealed class ElementType {
    class DoubleElement(val x: Double) : ElementType()
    class StringElement(val s: String) : ElementType()
    class IntElement(val i: Int) : ElementType()
}

fun handleList(l: List<ElementType>) {
    l.forEach {
        when (it) {
            is ElementType.DoubleElement -> handleDouble(it.x)
            is ElementType.StringElement -> handleString(it.s)
            is ElementType.IntElement -> handleInt(it.i)
        }
    }
}

      

+5


source


You can use type parameter functions to do this: inline

reified

inline fun <reified T : Any> classOfList(list: List<T>) = T::class

      

(runnable demo, including how to check type in instructions when

)



This solution is limited to cases where the actual type argument for T

is known at compile time, because the functions are inline

converted at compile time and the compiler replaces their type parameters with the reified

real type at each call site.

In the JVM, generic class type arguments are erased at runtime and there is basically no way to get them from arbitrary List<T>

(e.g. a list passed to a non-inline function as List<T>

- is T

not known at compile time for every call and is erased at runtime)

If you need more control over the type parameter reified inside a function, you can find this Q&A .

+5


source







All Articles