从类名字符串中获取TypeTag

时间:2014-05-21 13:59:24

标签: scala reflection

简单的问题,如何从类名获得TypeTag

基本上,Java中的TypeTag相当于Class.forName

注意:Manifest不会在这里为我做,我需要一个TypeTag。虽然如果有一种方法可以从清单转到typetag,那也可以,因为我可以从类名中获取清单。

3 个答案:

答案 0 :(得分:9)

不推荐使用清单,并且可能会在将来的Scala版本中消失。我认为依靠它们并不明智。您只能使用新的Scala反射来执行您想要的操作。

您可以从字符串转到Class以获取其类加载器,然后可以通过镜像从TypeTag创建Class,如this answer。这是一段稍微改编的代码,展示了它:

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

答案 1 :(得分:2)

您可以使用Class.forNameClass获取StringManifestFactory.classTypeManifest获取Class,然后scala.reflect.runtime.universe.manifestToTypeTag获得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))

答案 2 :(得分:0)

Type tags are always generated by the compiler。它们使用编译时信息进行实例化(即您的代码被重写)。无法在运行时实例化它们。