Kotlin中用Klaxon解析枚举数组遇运行时异常求助
解决Klaxon解析枚举数组时转换器未生效的问题
嘿,作为刚用Klaxon踩过类似坑的Kotlin新手,我太懂你这种运行时异常的崩溃感了!其实核心问题是:Klaxon默认不会自动把单个枚举的转换器应用到数组/列表的元素上,得我们手动给数组/列表类型专门注册转换器才行,下面给你两种实用的解决方案:
方案一:为枚举数组类型创建专属转换器
假设你的枚举类和包含枚举数组的数据类是这样的:
enum class Status { ACTIVE, INACTIVE, PENDING } data class User( val id: Int, val statuses: Array<Status> )
我们需要给Array<Status>类型写一个转换器,让Klaxon知道怎么把JSON数组里的字符串转成枚举数组:
class StatusArrayConverter : Converter { // 告诉Klaxon这个转换器负责处理Array<Status>类型 override fun canConvert(cls: Class<*>): Boolean { return cls == Array<Status>::class.java } // 把JSON数组解析成Status数组 override fun fromJson(jv: JsonValue): Any { val statusList = mutableListOf<Status>() jv.array?.forEach { jsonValue -> // 这里可以加容错逻辑,比如字符串不匹配时抛出友好异常或返回默认值 val statusStr = jsonValue.string ?: throw IllegalArgumentException("无效的Status值") statusList.add(Status.valueOf(statusStr)) } return statusList.toTypedArray() } // 把Status数组转成JSON字符串(如果需要序列化的话) override fun toJson(value: Any): String { val statusArray = value as Array<Status> return statusArray.joinToString(prefix = "[", postfix = "]") { "\"${it.name}\"" } } }
然后注册这个转换器到Klaxon实例,再解析JSON就没问题了:
val klaxon = Klaxon().converter(StatusArrayConverter()) // 示例JSON val json = """{"id": 1, "statuses": ["ACTIVE", "INACTIVE"]}""" val user = klaxon.parse<User>(json)
方案二:改用List(更符合Kotlin习惯)
数组在Kotlin里用起来不如List灵活,而且data class里的数组默认是引用比较,容易出问题。我们可以把数据类改成用List,然后给List<Status>写转换器:
修改数据类:
data class User( val id: Int, val statuses: List<Status> )
创建List专属转换器:
class StatusListConverter : Converter { override fun canConvert(cls: Class<*>): Boolean { // 检查是否是List类型,且泛型参数是Status return cls == List::class.java && cls.genericTypeArguments[0] == Status::class.java } override fun fromJson(jv: JsonValue): Any { return jv.array?.map { jsonValue -> val statusStr = jsonValue.string ?: throw IllegalArgumentException("无效的Status值") Status.valueOf(statusStr) } ?: emptyList() } override fun toJson(value: Any): String { val statusList = value as List<Status> return statusList.joinToString(prefix = "[", postfix = "]") { "\"${it.name}\"" } } }
注册并解析:
val klaxon = Klaxon().converter(StatusListConverter()) val user = klaxon.parse<User>(json)
额外注意事项
- 大小写敏感:JSON里的枚举字符串必须和Kotlin枚举的
name完全一致,如果JSON里是小写的active,你要么修改枚举名,要么在fromJson里做大小写兼容(比如Status.values().find { it.name.equals(statusStr, ignoreCase = true) }) - 容错处理:建议在转换器里加空值或无效值的处理,避免因为JSON里的脏数据直接崩溃
内容的提问来源于stack exchange,提问作者David Siegel
相关产品推荐
相关产品推荐

