Kotlin解析YAML时LinkedHashMap类型转换异常,如何获取数组?
问题解析与解决办法
这问题我之前处理YAML配置时也踩过同款坑,咱们一步步捋清楚来:
为什么println能正常打印,直接get却崩溃?
核心要搞懂两个关键逻辑:
- 泛型的编译检查与运行时擦除:你声明了
LinkedHashMap<String, String>,编译器在编译阶段会帮你做类型校验,但JVM运行时会把泛型信息擦除——实际yaml.load返回的是LinkedHashMap<String, Object>,其中accepted_groups对应的真实值是ArrayList类型,根本不是你声明的String。 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
相关产品推荐
相关产品推荐

