Kotlin 能够间接调用 Java(也就能够间接应用 Jackson, Gson 等 json 库),不过我看到有 official 的序列化库,于是钻研了一下。
重点看了下多态的序列化,的确十分简洁,先上代码感受一下:
@Serializable
sealed interface Reply
@Serializable
@SerialName("text")
class TextReply(val content: String): Reply
@Serializable
@SerialName("card")
class CardReply(val content: String, val cardId: Long = 1L): Reply
fun 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…