Search code examples
scalareflectiontypesparameterizedscala-option

Any way to access the type of a Scala Option declaration at runtime using reflection?


So, I have a Scala class that looks like this:

class TestClass {
  var value: Option[Int] = None
}

and I'm tackling a problem where I have a String value and I want to coerce it into that Option[Int] at runtime using reflection. So, in another piece of code (that knows nothing about TestClass) I have some code like this:

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)   
}

To do this, I need to know that the field is an Option and that the type parameter of the Option is Int.

What are my options for figuring out that the type of 'value' is Option[Int] at runtime (i.e. using reflection)?

I have seen similar problems solved by annotating the field, e.g. @OptionType(Int.class). I'd prefer a solution that didn't require annotations on the reflection target if possible.


Solution

  • It's quite streightforward using Java 1.5 reflection 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)
     }