Getting TypeTag from a classname string

2020-07-26 14:01发布

Simple question, how does one get a TypeTag from a classname?

So basically the TypeTag equivalent of Class.forName in Java.

Note: Manifest won't do for me here, I need a TypeTag. Although if there's a way to go from a manifest to a typetag, that would work too, as I can get a Manifest from the classname.

2条回答
家丑人穷心不美
2楼-- · 2020-07-26 14:42

You can use Class.forName to get a Class from a String, ManifestFactory.classType to get a Manifest from the Class, and then scala.reflect.runtime.universe.manifestToTypeTag to get a TypeTag:

import scala.reflect.runtime.universe
import scala.reflect.ManifestFactory

val className = "java.lang.String"
val mirror = universe.runtimeMirror(getClass.getClassLoader)
val cls = Class.forName(className)
val t = universe.manifestToTypeTag(mirror,
                                   ManifestFactory.classType(cls))
查看更多
forever°为你锁心
3楼-- · 2020-07-26 14:48

Manifests are deprecated and can probably disappear in future Scala versions. I don't think it is wise to rely on them. You can use only new Scala reflection to do what you want.

You can go from a string to a Class to get its class loader, and then it is possible to create a TypeTag from a Class through a mirror, as is outlined in this answer. Here is a slightly adapted piece of code demonstrating it:

import scala.reflect.runtime.universe._
import scala.reflect.api

def stringToTypeTag[A](name: String): TypeTag[A] = {
  val c = Class.forName(name)  // obtain java.lang.Class object from a string
  val mirror = runtimeMirror(c.getClassLoader)  // obtain runtime mirror
  val sym = mirror.staticClass(name)  // obtain class symbol for `c`
  val tpe = sym.selfType  // obtain type object for `c`
  // create a type tag which contains above type object
  TypeTag(mirror, new api.TypeCreator {
    def apply[U <: api.Universe with Singleton](m: api.Mirror[U]) =
      if (m eq mirror) tpe.asInstanceOf[U # Type]
      else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
  })
}
查看更多
登录 后发表回答