我正面临着一些非常基本的问题(以前在java中从未遇到过),可能是因为我缺乏Kotlin知识。
我目前正在尝试读取一个YML文件。所以我是这样做的:
private val factory = YamlConfigurationFactory(LinkedHashMap::class.java, validator, objectMapper, "dw")
关于配置的最佳下拉向导指南。
https://www.dropwizard.io/1.3.12/docs/manual/testing.html
因此在稍后的函数中,我会这样做。
val yml = File(Paths.get("config.yml").toUri())
var keyValues = factory.build(yml)
当使用我的调试器时,我可以看到有一个带有key->值的Map,就像它应该的那样。
现在当我使用keyValues.get("my-key")
type inference failed. the value of the type parameter k should be mentioned in input types
我试过了,但没有成功
var keyValues = LinkedHashMap<String, Any>()
keyValues = factory.build(yml)
YamlConfigurationFactory需要一个映射到的类,但我不知道是否有比当前解决方案+.kotlin更直接的方法来指定Kotlin类,比如
LinkedHashMap::class.java.kotlin
这里它还抛出了一个错误。
想法?
发布于 2019-07-15 15:45:49
这是一个典型的JVM泛型问题。Class<LinkedHashMap>
没有携带关于它的键和值的实际类型的信息,所以keyValues
变量总是以LinkedHashMap<*, *>
类型结束,因为它不能在编译时进行检查。有两种方法可以解决这个问题:
不安全的造型
这就是在标准Java语言中处理这个问题的方法:只需将LinkedHashMap<*, *>
转换为LinkedHashMap<String, Any>
(或任何实际期望的类型)。这会产生一个警告,因为编译器无法验证强制转换是否安全,但众所周知,在处理JVM泛型和序列化时,这种情况通常是不可避免的。
YamlConfigurationFactory(LinkedHashMap::class.java, ...) as LinkedHashMap<String, Any>
类型推断魔术
在使用Kotlin时,您可以通过实际显式创建Class<LinkedHashMap<String, Any>>
实例来避免强制转换。当然,由于这仍然是JVM,您将在运行时丢失所有类型信息,但这应该足以告诉类型推理引擎您的结果应该是什么。然而,你需要一个特殊的帮助器方法(或者至少我还没有找到一个更简单的解决方案),但是这个方法只需要在你的项目中的某个地方声明一次:
inline fun <reified T> classOf(): Class<T> = T::class.java
...
val factory = YamlConfigurationFactory(classOf<LinkedHashMap<String, Any>>(), ...)
使用这个"hack",你将直接获得LinkedHashMap的一个实例,但是,请记住,这只是类型推理引擎的额外信息,但它实际上只是隐藏了不安全的强制转换。此外,如果类型在编译类型(reified
)中未知,则不能使用此方法。
https://stackoverflow.com/questions/57042091
复制