Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get ParameterizedType from scala's Type?

Tags:

generics

scala

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)
}
like image 721
user48956 Avatar asked Jul 07 '16 22:07

user48956


1 Answers

  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

like image 53
devshorts Avatar answered Oct 16 '22 02:10

devshorts