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.
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.")
})
}
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With