Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the KClass for a Kotlin constructor parameter

Using Kotlin reflection, I am trying to check the KClass of each parameter of a class's primary constructor.

Given a simple data class like this:

data class MyPerson(val name: String, val age: Int)
val modelClass = MyPerson::class

I get its primary constructor val primaryConstructor = modelClass.primaryConstructor. For each parameter, I want to check its class (is it Kotlin.String, Kotlin.Int etc). Something like this:

for (param in primaryConstructor.parameters) {
  when(param.type) {
    is Kotlin.String -> // do string thing
    is Kotlin.Int -> // do int thing
}

Unfortunately, this isn't valid code. I've tried param.type, param.classifier, param.type.jvmErasure and others. The closest I've found is param.type.jvmErasure.qualifiedName, which gives me a String with the fully qualified name of the KClass. But I really want the KClass.

Is this possible at all?

like image 882
ljd Avatar asked Mar 28 '18 18:03

ljd


People also ask

What is KClass in Kotlin?

The KClass type is Kotlin's counterpart to Java's java. lang. Class type. It's used to hold references to Kotlin classes; you'll see what it lets you do with those classes in the “Reflection” section later in this chapter. The type parameter of KClass specifies which Kotlin classes can be referred to by this reference.

How do you use constructor parameters in Kotlin?

The primary constructor is initialized in the class header, goes after the class name, using the constructor keyword. The parameters are optional in the primary constructor. The constructor keyword can be omitted if there is no annotations or access modifiers specified.

How many constructors can a class have in Kotlin?

A class in Kotlin can have at most one primary constructor, and one or more secondary constructors. The primary constructor initializes the class, while the secondary constructor is used to initialize the class and introduce some extra logic.

How to create an instance of a kclass in Kotlin?

As of Kotlin 1.1, the extension function createInstance () on KClass tokens can create object instances: This extension function only works for classes with no-arg constructors or constructors with only optional parameters. Therefore, we can create an instance of the OptionalArgs class, as well:

Does Kotlin use no-args Constructors?

This way, Kotlin can work well with such libraries as Jackson or JPA, which use the no-args constructor to create class instances: 3. Initializing Properties from Constructor Parameters

What is it () function in Kotlin?

It is a special member function that is called when an object is instantiated (created). However, how they work in Kotlin is slightly different. In Kotlin, there are two constructors:


2 Answers

The param.type expression returns a KType, so you need to get the appropriate Ktype instances to check against:

for (param in primaryConstructor.parameters) {
    when (param.type) {
        String::class.createType() -> println("String param")
        Int::class.createType() -> println("Int param")
    }
}

Side note: might be a good idea to not create these every time in the loop:

val stringType = String::class.createType()
val intType = Int::class.createType()
for (param in primaryConstructor.parameters) {
    when (param.type) {
        stringType -> println("String param")
        intType -> println("Int param")
    }
}
like image 125
zsmb13 Avatar answered Nov 10 '22 03:11

zsmb13


You can use the javaType property of KType for that comparison:

when (param.type.javaType) {
    String::class.java -> println("String!")
    Int::class.java -> println("Int!")
}
like image 29
s1m0nw1 Avatar answered Nov 10 '22 05:11

s1m0nw1