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.