klaxon
klaxon copied to clipboard
Polymorphic field serialization uses the converter based on the declared field type, not the type of the field value
abstract class Animal
class Dog : Animal(val favouritePark: String)
class Cat : Animal(val favouriteWindow: String)
data class PetStore(val cutestAnimal: Animal)
class DogConverter: Converter {
override fun canConvert(cls: Class<*>): Boolean = cls == Dog::class.java
override fun fromJson(jv: JsonValue): Any? = TODO("Not yet implemented")
override fun toJson(value: Any): String = "Dog!"
}
class CatConverter: Converter {
override fun canConvert(cls: Class<*>): Boolean = cls == Cat::class.java
override fun fromJson(jv: JsonValue): Any? = TODO("Not yet implemented")
override fun toJson(value: Any): String = "Cat!"
}
val petStore = PetStore(Dog("Central"))
val klaxon = Klaxon().converter(DogConverter()).converter(CatConverter())
klaxon.toJsonString(petStore)
Expected: {"cutestAnimal": "Dog!"}
Actual: {"cutestAnimal": {}}
From examine the code, it looks like the declare class type of the property takes precedence over the class of the actual value: https://github.com/cbeust/klaxon/blob/master/klaxon/src/main/kotlin/com/beust/klaxon/Klaxon.kt#L265
val toConvert = prop?.returnType?.javaType as? Class<*> ?: cls
I don't think this is the best approach as for polymorphic types, typically the specialized converter should be used