Kotlin能够间接调用 Java(也就能够间接应用 Jackson, Gson 等json库),不过我看到有 official 的序列化库,于是钻研了一下。
重点看了下多态的序列化,的确十分简洁,先上代码感受一下:
@Serializablesealed interface Reply@Serializable@SerialName("text")class TextReply(val content: String): Reply@Serializable@SerialName("card")class CardReply(val content: String, val cardId: Long = 1L): Replyfun main() { val reply: Reply = CardReply("A card", 2L) // 序列化 val jsonString = Json.encodeToString(reply) println(jsonString) // 反序列化,隐式 val decodedReply: Reply = Json.decodeFromString(jsonString) println(decodedReply) // 显式 println( Json.decodeFromString<Reply>(jsonString) )}
Output:
{"type":"card","content":"A card","cardId":2}[email protected][email protected]
CardReply
& TextReply
实现了 Reply
,能够看到序列化后果主动加上了类型标识"type": "card"
。
再来看看泛型的序列化,同样非常简洁:
fun main() { // 列表序列化 val jsonList = Json.encodeToString( listOf(CardReply("A card"), TextReply("A text")) ) println(jsonList) // 列表反序列化 val replies: List<Reply> = Json.decodeFromString(jsonList) println(replies)}
Output:
[{"type":"card","content":"A card"},{"type":"text","content":"A text"}][[email protected], [email protected]]
能够看到,泛型没有失落,good。
用过 Jackson 的同学应该晓得这个神坑,给个单元测试感受一下:
public class ReplyTest { @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, defaultImpl = CardReply.class ) @JsonSubTypes({ @JsonSubTypes.Type(value = CardReply.class, name = "card") }) interface Reply { } static class CardReply implements Reply { } @Test void fuck() throws JsonProcessingException { System.out.println( JsonUtil.toStr(new CardReply()) ); String json = JsonUtil.toStr( Collections.singletonList(new CardReply()) ); System.out.println(json); }}
Output:
{ "@type" : "card" }[ { } ]
能够看到,List<Reply>
序列化后果失落了泛型,令人丧气。
至此,Kotlin 给人感觉还不错,代码简洁,对多态反对良好。
详情请参考官网库:https://github.com/Kotlin/kot...