Kotlin reflection - How to get class reference from KParameter
I have a class reference and a set of data for initializing the class, I need to create instance of that class dynamically. I get the constructor from the class reference, I loop through its parameters and do a match between that set of data. Then call the constructor.callby(param). All is fine, until one of the property is a custom class rather than a kotlin type like kotlin.Int. Let’s see how to solve it.
Some setup
1 | data class Student( |
The above code is simple, we retrieve a class and its constructor, then we loop through its parameters.
Now you can do the match up thing to restore the class.
Get the class reference from KParameter
1 | fun generateClass(param:KParameter):Any? { |
In the above forEach, when we found that the parameter is a custom class, we need to do something about it. First, we make sure it’s not a kotlin type by checking the paramName not startsWith("kotlin"), all kotlin types are started from kotlin even for Collection type.
Then we return param.type.classifier as KClass<*>, then you can repeat the code in Some setup to restore this nested property.
Get the class reference from KParameter which is a List<*>
But what happen if the property is not a custom class, but also a List<CustomClass>. Like the lessons property in the following Student class.
1 | data class Lesson( |
We need to refactor our generateClass function.
1 |
|
Here things get a little bit interesting. First, we check it’s a List type, then we type to retrieve the item type of that list. Let’s say it’s a kotlin.collections.List<kotlin.Int>, then it’s not a list of custom class. But if the itemTypeName is not startsWith("kotlin"), then it is a custom class.
Then we retrieve the item type by using param.type.arguments[0].type?.classifier as KClass<*>
End
That’s all, hope it helps. :)
Thanks for reading!
Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.