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.
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))
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.")
})
}