genericskotlinparameter-passinggeneric-type-argument

How to pass a type to generic method in Kotlin?


I have a generic method like below

private fun <T> getSomething(): T {
    return "something" as T
}

How can I call this method with a variable T type?

val types = arrayListOf<Type>(String::class.java, Boolean::class.java)
types.forEach { type ->
    val something = getSomething<type>() // Unresolved reference: type
}

At runtime, I don't know what would be generic type T. I am getting the type from types and should pass it with generic getSomething method.

Use case

I want to call database which has several table. Example models are like this

class User{

}

class Student{

}

Since all the calling queries are basically same, I want to have generic method for calling database and get data.

private fun <T> getData(model: String): List<T>?{
    return when(model){
        "user" -> getUsers()
        "student" -> getStudents()
        else -> null
    }
}

So when I call above method. Within my loop I want to pass Type as either User or Student.

val types = arrayListOf<Type>(User::class.java, Student::class.java)
types.forEach { type ->
    val data = getData<type>(type.javaClass.simpleName) // Unresolved reference: type in <type>
}

How can I achieve it.


Solution

  • Here's a complete example:

    import kotlin.reflect.KClass
    
    data class User(val name: String)
    data class Student(val name: String)
    
    fun getUsers(): List<User> = listOf(User("JB"))
    fun getStudents(): List<Student> = listOf(Student("Claire"))
    
    fun <T: Any> getData(clazz: KClass<T>): List<T>? {
        return when(clazz) {
            User::class -> getUsers() as List<T>
            Student::class -> getStudents()  as List<T>
            else -> null
        }
    }
    
    fun main(args: Array<String>) {
        val types = listOf(User::class, Student::class)
        types.forEach { type ->
            val data = getData(type)
            println(data)
        }
    }