I have a Kotlin class with two generic parameterized types, but when I try to use it, I get this error: "Only KClass supported as classifier, got K". How can I fix it without changing client code (main method)?
Code:
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.io.File
class KeyValueStore<K, V>(filePath: String) {
val dbFile = File(filePath)
fun read(): Map<K, V> {
if (!dbFile.exists()) {
return mapOf()
}
val content = dbFile.readText()
return Json.decodeFromString(content)
}
fun write(data: Map<K, V>) {
val content = Json.encodeToString(data)
dbFile.writeText(content)
}
}
fun main() {
val s = KeyValueStore<String, Int>("test.db")
s.write(mapOf("a" to 1))
}
Exception:
Exception in thread "main" java.lang.IllegalStateException: Only KClass supported as classifier, got K
at kotlinx.serialization.internal.Platform_commonKt.kclass(Platform.common.kt:102)
at kotlinx.serialization.SerializersKt__SerializersKt.serializerByKTypeImpl$SerializersKt__SerializersKt(Serializers.kt:78)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:59)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source)
at kotlinx.serialization.SerializersKt__SerializersKt.builtinSerializer$SerializersKt__SerializersKt(Serializers.kt:96)
at kotlinx.serialization.SerializersKt__SerializersKt.serializerByKTypeImpl$SerializersKt__SerializersKt(Serializers.kt:84)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:59)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source)
at utils.KeyValueStore.write(KeyValueStore.kt:97)
at utils.KeyValueStoreKt.main(KeyValueStore.kt:91)
at utils.KeyValueStoreKt.main(KeyValueStore.kt)
This problem doesn't happen when I replace all generic type parameters with fixed types like String for K, and Int for V.
It probably has something to do with the need for reified types, and I tried something complex like this below, but I still get the same error:
class KeyValueStore2<K: Any, V: Any> @PublishedApi internal constructor(
private val classK: KClass<K>,
private val classV: KClass<V>
) {
val dbFile = File("test.db")
companion object {
@JvmStatic
@JvmName(name = "create")
inline operator fun <reified K : Any, reified V: Any> invoke() =
KeyValueStore2(K::class, V::class)
}
...
}
Edit: this question is related to Deserialize generic object using Kotlin Serialization, but different in that my question is about a generic class instead of function. Generic classes are more complex and less flexible than standalone generic functions.