user48956
user48956

Reputation: 15810

Get ParameterizedType from scala's Type?

Helpfully, scala's universe.typeOf preserves the type parameters of a class.

import scala.reflect.runtime.universe._

case class X[T:TypeTag]() {
  val t = typeOf[T] // e.g. Seq[Int]  Holds type parameters
  val clz:Class[_] = runtimeMirror(this.getClass.getClassLoader).runtimeClass(t.typeSymbol.asClass)
}

X[Seq[Int]]().t // Seq[Int]
X[Seq[Int]]().clz // Seq    :-(

Java's ParameterizedType holds the same un-erased information. How can I convert a scala Type into an Java ParameterizedType?

import scala.reflect.runtime.universe._

case class X[T:TypeTag]() {
  val clz:Class[_] = runtimeMirror(this.getClass.getClassLoader).runtimeClass(typeOf[T].typeSymbol.asClass)
}

Upvotes: 6

Views: 323

Answers (1)

devshorts
devshorts

Reputation: 8872

  private def parameterizedType(paramType: Type): java.lang.reflect.Type = {
    val typeConstructor = currentMirror.runtimeClass(paramType)

    val innerTypes = paramType.typeArgs.map(parameterizedType).toArray

    if (innerTypes.isEmpty) {
      typeConstructor
    } else {
      new ParameterizedType {
        override def getRawType: reflect.Type = {
          typeConstructor
        }

        override def getActualTypeArguments: Array[reflect.Type] = {
          innerTypes
        }

        override def getOwnerType: reflect.Type = {
          null
        }
      }
    }
  }

  def makeType[T : TypeTag]: reflect.Type = {
      parameterizedType(typeOf[T])
  }

Seems to do the trick. Basically just iterating through the parameterized types and converting it to a java parameterized type object

Upvotes: 3

Related Questions