You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin解析YAML时LinkedHashMap类型转换异常,如何获取数组?

问题解析与解决办法

这问题我之前处理YAML配置时也踩过同款坑,咱们一步步捋清楚来:

为什么println能正常打印,直接get却崩溃?

核心要搞懂两个关键逻辑:

  1. 泛型的编译检查与运行时擦除:你声明了LinkedHashMap<String, String>,编译器在编译阶段会帮你做类型校验,但JVM运行时会把泛型信息擦除——实际yaml.load返回的是LinkedHashMap<String, Object>,其中accepted_groups对应的真实值是ArrayList类型,根本不是你声明的String。
  2. println的底层逻辑:println(obj.get("accepted_groups"))并没有做强制类型转换,它只是调用了这个对象的toString()方法。不管对象是ArrayList还是String,只要不为null,toString()都会返回对应的字符串表示(比如ArrayList的toString()就是[A, B]),所以看起来能正常打印,但这个值的实际类型和你声明的泛型完全不匹配。

而当你写val group = obj.get("accepted_groups")时,编译器会根据你声明的泛型自动插入String类型的强制转换,运行时发现实际是ArrayList,自然就抛出ClassCastException了。

怎么正确获取数组(列表)?

核心是修正泛型声明,让它匹配YAML的实际结构,再安全做类型转换:

方案1:用Any接收所有类型,安全转换

val yaml = Yaml()
val inputStream: InputStream = FileInputStream("permissions.yml")
// 用Any接收所有类型的value,适配YAML里的不同结构
val obj = yaml.load<LinkedHashMap<String, Any>>(inputStream)

// 用as?做安全转换,转换失败时返回空列表避免崩溃
val acceptedGroups = obj["accepted_groups"] as? List<String> ?: emptyList()
println(acceptedGroups) // 正常输出[A, B]

方案2:用自定义数据类解析(更推荐)

如果你的YAML结构固定,可以直接定义对应的数据类,让解析更优雅、类型更安全:

// 定义和YAML结构匹配的数据类
data class PermissionsConfig(
    val accepted_groups: List<String>,
    // 其他配置项可以在这里补充,比如 val admin_group: String
)

// 直接解析成数据类
val yaml = Yaml()
val inputStream: InputStream = FileInputStream("permissions.yml")
val config = yaml.load<PermissionsConfig>(inputStream)
println(config.accepted_groups) // 直接获取列表,无需额外转换

内容的提问来源于stack exchange,提问作者StackUnderflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:13:24