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。