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?
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.
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.
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.
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:
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
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:
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")
}
}
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!")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With