在使用kotlinx.serialization时,可以使用@Serializer注解为接口注册全局类型适配器,而无需在每个类上添加注释。下面是具体的步骤:
以下是一个示例代码:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
interface Shape {
fun draw()
}
@Serializable
data class Circle(val radius: Double) : Shape {
override fun draw() {
println("Drawing a circle with radius $radius")
}
}
@Serializable
data class Rectangle(val width: Double, val height: Double) : Shape {
override fun draw() {
println("Drawing a rectangle with width $width and height $height")
}
}
class ShapeSerializer : KSerializer<Shape> {
override val descriptor: SerialDescriptor =
PolymorphicClassDescriptor(listOf(SerialDescriptor("Circle"), SerialDescriptor("Rectangle")))
override fun serialize(encoder: Encoder, value: Shape) {
when (value) {
is Circle -> encoder.encodeSerializableValue(Circle.serializer(), value)
is Rectangle -> encoder.encodeSerializableValue(Rectangle.serializer(), value)
}
}
override fun deserialize(decoder: Decoder): Shape {
val input = decoder as? JsonInput ?: error("The decoder is not JsonInput")
val json = input.decodeJson()
return when (json.jsonObject["type"]?.primitive?.content) {
"Circle" -> input.json.decodeSerializableValue(Circle.serializer())
"Rectangle" -> input.json.decodeSerializableValue(Rectangle.serializer())
else -> throw SerializationException("Unknown shape type")
}
}
}
fun main() {
val shapeSerializer = ShapeSerializer()
val json = Json { serializersModule = SerializersModule { contextual(Shape::class, shapeSerializer) } }
val circle = Circle(5.0)
val rectangle = Rectangle(3.0, 4.0)
val circleJson = json.encodeToString(Circle.serializer(), circle)
val rectangleJson = json.encodeToString(Rectangle.serializer(), rectangle)
println(circleJson) // Output: {"type":"Circle","radius":5.0}
println(rectangleJson) // Output: {"type":"Rectangle","width":3.0,"height":4.0}
val decodedCircle = json.decodeFromString<Shape>(circleJson)
val decodedRectangle = json.decodeFromString<Shape>(rectangleJson)
decodedCircle.draw() // Output: Drawing a circle with radius 5.0
decodedRectangle.draw() // Output: Drawing a rectangle with width 3.0 and height 4.0
}
在上面的示例代码中,我们创建了一个Shape接口和两个实现类Circle和Rectangle。然后,我们实现了ShapeSerializer作为全局类型适配器,将Shape接口和对应的实现类进行了注册。在使用Json实例进行序列化和反序列化时,会自动使用注册的类型适配器。
领取专属 10元无门槛券
手把手带您无忧上云