Scala 从类名字符串获取TypeTag

Scala 从类名字符串获取TypeTag,scala,reflection,Scala,Reflection,一个简单的问题,如何从类名中获得TypeTag 因此基本上,TypeTag相当于Java中的Class.forName 注意:清单在这里不适合我,我需要一个TypeTag。尽管有一种方法可以从清单到类型标记,但这也会起作用,因为我可以从类名中获取清单。您可以使用Class.forName从字符串中获取类,ManifestFactory.classType从类中获取清单,然后scala.reflect.runtime.universe.manifestToTypeTag获取TypeTag: imp

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

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


注意:清单在这里不适合我,我需要一个TypeTag。尽管有一种方法可以从清单到类型标记,但这也会起作用,因为我可以从类名中获取清单。

您可以使用
Class.forName
字符串
中获取
ManifestFactory.classType
中获取
清单
,然后
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))

清单已弃用,可能会在未来的Scala版本中消失。我认为依靠他们是不明智的。您只能使用新的Scala反射来执行您想要的操作

您可以从字符串转到
以获取其类加载器,然后可以通过镜像从
创建
类型标签
,如中所述。下面是一段稍加修改的代码,演示了这一点:

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.")
  })
}
导入scala.reflect.runtime.universe_
导入scala.reflect.api
def stringToTypeTag[A](名称:String):TypeTag[A]={
val c=Class.forName(name)//从字符串中获取java.lang.Class对象
val mirror=runtimeMirror(c.getClassLoader)//获取运行时镜像
val sym=mirror.staticClass(name)//获取'c'的类符号`
val tpe=sym.selfType//获取'c'的类型对象`
//创建包含上述类型对象的类型标记
TypeTag(镜像,新api.TypeCreator{

def应用[U你可能会得到一个
类标签
,似乎。一个类标签可能就可以了。我只想从类的FQN中得到一个case类的字段。如果必须的话,我可以用Java反射进行黑客攻击。注意:这对泛型不起作用,因此如果足够的话,最好返回
类标签
。有一种方法可以创建
使用泛型的TypeTag
。请参考以下答案:这会捕获嵌套类型吗?例如,这会与“List[Int]”一起工作吗?不,不会,因为
Class.forName
需要正确的Java类名。在
stringToTypeTag[A]中
[A]
有什么作用
mean?我认为我们不能提供
A
,因为我们正在为具有类名的A获取类型标记。@Tom这是为了便于使用。即使您希望通过类名获取类型标记,您仍然需要指定某些类型,因为
TypeTag
是参数化的;此定义允许指定您需要的任何类型,这当然是必要的危险(不能保证它与类名标识的类型相同),但也很方便,因为您不需要执行
.asInstanceOf
s。