我需要从给定Enum的Class实例的字符串中获取Java枚举值。我尝试了下面的代码,但我得到“未绑定的通配符类型”编译错误。似乎,我需要对存在类型做一些事情,对于某些事情,但是我无法理解如何做到这一点。
val paramClass = method.getParameterTypes()(0)
val value = paramClass match {
case _ if classOf[Enum[_]].isAssignableFrom(paramClass) => Enum.valueOf[_ <: Enum[_]](paramClass.asInstanceOf[Class[_ <: Enum[_]]], "MYENUM")
答案 0 :(得分:7)
def enumValueOf[T <: Enum[T]](cls: Class[_], stringValue: String): Enum[_] =
Enum.valueOf(cls.asInstanceOf[Class[T]], stringValue).asInstanceOf[Enum[_]]
val value = paramClass match {
case _ if classOf[Enum[_]].isAssignableFrom(paramClass) => enumValueOf(paramClass, "MYENUM")
case _ => // other cases
}
我认为我们需要这种复杂性的原因......
我们需要编译器相信我们所拥有的Class[_]
实际上是Class[T <: Enum[T]]
(当然,这是一个初步测试,这确实是一个Java枚举 - 就像你的代码中所做的那样 - 需要)。因此,我们将cls
转换为Class[T]
,其中T
由编译器推断为<: Enum[T]
。但是编译器仍然需要找到合适的T
,默认为Nothing
。因此,就编译器而言,cls.asInstanceOf[Class[T]]
是Class[Nothing]
。这是暂时确定,因为它可用于调用Enum.valueOf
- 问题是推断的返回类型valueOf
当然也是Nothing
。这里我们遇到了一个问题,因为当我们尝试实际使用类型为Nothing
的实例时,编译器会插入一个异常。因此,我们最终将valueOf
的返回值转换为Enum[_]
。
然后诀窍是始终让编译器推断出enumValueOf
的类型参数,并且永远不会尝试自己指定它(因为我们不应该知道它) - 从而提取对{的调用{1}}在另一种方法中,让编译器有机会绑定Enum.valueOf
。
正如我所说,我对这个解决方案不太满意,看起来比应该更复杂......
更新:我稍微简化了代码。