Reputation: 1441
I have a val built like this
val qs = hashMapOf<KProperty1<ProfileModel.PersonalInfo, *> ,Question>()
How can I obtain the class of ProfileModel.PersonalInfo from this variable?
In other words what expression(involving qs of course) should replace Any so that this test passes.
@Test
fun obtaionResultTypeFromQuestionList(){
val resultType = Any()
assertEquals(ProfileModel.PersonalInfo::class, resultType)
}
Thank you for your attention
Upvotes: 1
Views: 711
Reputation: 10106
There is no straight way to get such information due to Java type erasure.
To be short - all information about generics (in your case) is unavailable at runtime and HashMap<String, String>
becomes HashMap
.
But if you do some changes on JVM-level, like defining new class, information about actual type parameters is kept. It gives you ability to do some hacks like this:
val toResolve = object : HashMap<KProperty1<ProfileModel.PersonalInfo, *> ,Question>() {
init {
//fill your data here
}
}
val parameterized = toResolve::class.java.genericSuperclass as ParameterizedType
val property = parameterized.actualTypeArguments[0] as ParameterizedType
print(property.actualTypeArguments[0])
prints ProfileModel.PersonalInfo
.
Explanation:
HashMap< ... , ... >
HashMap
generic brackets. It gives us KProperty1< ... , ... >
KProperty1
Kotlin is tied to the JVM type erasure as well as Java does. You can do a code a bit nice by moving creation of hash map to separate function:
inline fun <reified K, reified V> genericHashMapOf(
vararg pairs: Pair<K, V>
): HashMap<K, V> = object : HashMap<K, V>() {
init {
putAll(pairs)
}
}
...
val hashMap = genericHashMapOf(something to something)
Upvotes: 4