有什么方法可以在运行时使用反射访问Scala Option声明的类型?

Gra*_*Lea 13 reflection types scala parameterized scala-option

所以,我有一个看起来像这样的Scala类:

class TestClass {
  var value: Option[Int] = None
}
Run Code Online (Sandbox Code Playgroud)

我正在解决一个问题,我有一个String值,我想在运行时使用反射将其强制转换为Option [Int].所以,在另一段代码中(对TestClass一无所知)我有一些这样的代码:

def setField[A <: Object](target: A, fieldName: String, value: String) {
  val field = target.getClass.getDeclaredField(fieldName)
  val coercedValue = ???; // How do I figure out that this needs to be Option[Int] ? 
  field.set(target, coercedValue)   
}
Run Code Online (Sandbox Code Playgroud)

为此,我需要知道该字段是一个Option,并且Option的type参数是Int.

我可以选择在运行时(即使用反射)确定'value'的类型是Option [Int]?

我已经看到通过注释字段解决了类似的问题,例如@OptionType(Int.class).如果可能的话,我更喜欢不需要在反射目标上进行注释的解决方案.

Ale*_*xey 5

使用Java 1.5反射API非常简单:

 def isIntOption(clasz: Class[_], propertyName: String) = {
   var result = 
     for {
       method <- cls.getMethods
       if method.getName==propertyName+"_$eq"
       param <- method.getGenericParameterTypes.toList.asInstanceOf[List[ParameterizedType]]
     } yield
       param.getActualTypeArguments.toList == List(classOf[Integer]) 
       && param.getRawType == classOf[Option[_]]
   if (result.length != 1)
     throw new Exception();
   else
     result(0)
 }
Run Code Online (Sandbox Code Playgroud)

  • 我发现我的Scala案例类(scala 2.10)的“ Option [Int]”的“ GenericParameterType”是“ Object”。有什么办法可以恢复`Int`类型? (4认同)
  • Scala会自动使用以下方法包装字段:foo代表getter,foo_ $ eq代表setter,因此最好使用这些包装方法,然后再使用字段-以防在子类中被覆盖。否则,您将破坏子类的预期行为。 (2认同)