In Scala Reflection, How to get generic type parameter of a concrete subclass?

后端 未结 2 824
攒了一身酷
攒了一身酷 2020-12-19 03:53

Assuming that I have a Generic superclass:

class GenericExample[T](
                         a: String,
                         b: T
                                


        
2条回答
  •  渐次进展
    2020-12-19 04:22

    There are two approaches which I can suggest:

    1) Reveal generic type from base class:

    import scala.reflect.runtime.universe._
    
    class GenericExample[T: TypeTag](a: String, b: T) {
      def fn(i: T) = "" + b + i
    }
    
    case class Example(a: String, b: Int) extends GenericExample[Int](a, b) {}
    
    val classType = typeOf[Example].typeSymbol.asClass
    val baseClassType = typeOf[GenericExample[_]].typeSymbol.asClass
    val baseType = internal.thisType(classType).baseType(baseClassType)
    
    baseType.typeArgs.head // returns reflect.runtime.universe.Type = scala.Int
    

    2) Add implicit method which returns type:

    import scala.reflect.runtime.universe._
    
    class GenericExample[T](a: String, b: T) {
      def fn(i: T) = "" + b + i
    }
    
    case class Example(a: String, b: Int) extends GenericExample[Int](a, b)
    
    implicit class TypeDetector[T: TypeTag](related: GenericExample[T]) {
      def getType(): Type = {
        typeOf[T]
      }
    }
    
    new Example("", 1).getType() // returns reflect.runtime.universe.Type = Int
    

提交回复
热议问题