Search code examples
scalareflection

Finding type of List on Scala case class declared field via reflection


I have a Scala case class with a List declared as:

  AuxiliaryImages: List[MimeInfo],

I get the field type using reflection:

  private def ft(fieldName: String): Class[_] = {
    val field = classOf[CatalogItemRecord].getDeclaredField(fieldName)
    field.getType
  }

I need conditional logic based on the type of the List:

  if (ft("AuxiliaryImages") == classOf[List[MimeInfo]]) {

But it seems I'm losing the list type List[MimeInfo]] as I get scala.collection.immutable.List for the field type.

Is there a way to get the list type List[MimeInfo]] via reflection on declared fields?


Solution

  • You should use Field#getGenericType instead of Field#getType. Try

    def ft(fieldName: String): (Class[_], Seq[Class[_]]) = {
      val field = classOf[CatalogItemRecord].getDeclaredField(fieldName)
      field.getGenericType match {
        case pt: ParameterizedType =>
          val cls = pt.getRawType match {
            case c: Class[_] => c
          }
          val argClasses = pt.getActualTypeArguments.map {
            case c: Class[_] => c
          }.toSeq
          (cls, argClasses)
      }
    }
    
    ft("AuxiliaryImages") == (classOf[List[_]], Seq(classOf[MimeInfo])) // true i.e. List[MimeInfo]
    ft("AuxiliaryImages") == (classOf[List[_]], Seq(classOf[Int])) // false i.e. not List[Int]