Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting TypeTag from a classname string

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.

like image 627
sksamuel Avatar asked Feb 06 '26 01:02

sksamuel


2 Answers

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.")
  })
}
like image 119
Vladimir Matveev Avatar answered Feb 07 '26 23:02

Vladimir Matveev


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))
like image 29
Dan Getz Avatar answered Feb 07 '26 22:02

Dan Getz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!