Determining the type of a function parameter


#1

Using reflection, I am examining the constructor parameters of a Kotlin class. I need to determine the class (KClass) of each parameter and to take appropriate action:

for(consP in primaryConstructor.parameters) {
 when(consP.type) { 
is kotlin.String -> // do String thing;
 is kotlin.Int -> // do Int thing }
 }

Unfortunately, the closest I’ve found uses jvmErasure and gives me just the qualified name of the parameter:

when(consP.type.jvmErasure.qualifiedName) {
  is "kotlin.String" -> // do String thing;
  is "kotlin.Int" -> // do Int thing;
}

Is it possible to do what I want without comparing strings? I’m particularly worried about what happens when the class contains Java parameter types (like java.lang.String), and don’t want to have to deal with every possible qualified name for Kotlin and Java types.

Edit: I’ve found consP.type.jvmErasure.java, which returns the underlying Java class or primitive. But I’m still looking for the KClass :frowning:


#2

Using consP.type.jvmErasure as you said you could more or less achieve it:

fun main(args: Array<String>) {
    Something::class.primaryConstructor?.parameters?.forEach {
        when (it.type.jvmErasure) {
            String::class -> println("I'm a String")
            Int::class -> println("I'm an Int")
            List::class -> println("I'm a List")
            else -> println("I don't what I am")
        }
    }
}

class Something(string: String, integer: Int, list: List<String>, other: Long)

That code outputs:

I'm a String
I'm an Int
I'm a List
I don't what I am

#3

Oh, thank you! I’ve been struggling for days. I had tried it.type.jvmErasure but I thought you had to use the is operator when checking the class in a when block. So it completely failed.


#4

The is if when you want to use type literals. This code just compares KClass objects - it is reflection based.