Reputation: 8096
Lets pretend we have an interface which defines the storage of data in some database by serializing them into json.
interface StorageApi {
suspend fun store(key: String, value: Any)
// inline suspend fun <reified T: Any> get(key: String): T // reification is not possible in interfaces since we can't inline them
suspend fun <T: Any> get(key: String, kClass: KClass<T>): T // so I have to stick with some other way, like reflection.
}
And then we have an implementation of the method:
override suspend fun <T : Any> get(key: String, kClass: KClass<T>): T {
val value = // some query to database
return Klaxon().parse<T>(value) // obviously error by compiler since T goes through type-erasure
}
Here I cannot use T as it would go through Type-erasure at runtime. I have reflection but don't know how to use it in this purpose. The Klaxon.parse()
function does not accept KClass for getting types.
Is there any way to bypass these or make some utility to use reflection in this purpose, or any other possible workarounds?
Upvotes: 0
Views: 404
Reputation: 89548
I am fairly sure that if you break the inlined reification chain at any point, and start working with classes (KClass
instances, that is), there is unfortunately no going back, exactly for the reasons you've described.
What's even worse is that a KClass
can't hold type parameters, so if your reified parameter was a List<Something>
for example, then you've lost information there already - another reason for no going back to reification.
The sad conclusion is that you probably have to deal with KClass
in a case like this.
Upvotes: 1