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...