在斯卡拉,我希望能够说
val user = Node.create[User](...) // return User object
所以这就是我到目前为止所拥有的:
def create[T : TypeTag](map: Map[String, Any]) {
val type = typeOf[T]
// create class from type here???
}
Run Code Online (Sandbox Code Playgroud)
我一直在研究如何从泛型类创建类,并发现使用ClassManifest似乎已被弃用.相反,类型标签在这里,所以我能够做类似这个typeOf [T]的东西,实际上得到类型..但后来我迷路了.如果我可以获得该类,那么我可以使用类似class.newInstance的东西并从那里手动设置字段.
问题是:给定一个类型,我可以获得给定类型的类实例吗?
事实上最简单的方法是使用ClassTag:
def create[T : ClassTag](map: Map[String, Any]): T = {
val clazz: Class[_] = classTag[T].runtimeClass
clazz.newInstance(<constructor arguments here>).asInstanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)
ClassTag是一个围绕Java的瘦包装器Class,主要用于数组实例化.
TypeTag设施更强大.首先,您可以使用它来调用Java反射:
import scala.reflect.runtime.universe._
def create[T: TypeTag](map: Map[String, Any]): T = {
val mirror = runtimeMirror(getClass.getClassLoader) // current class classloader
val clazz: Class[_] = mirror.runtimeClass(typeOf[T].typeSymbol.asClass)
clazz.newInstance(<constructor arguments here>).asInstanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)
但是,Scala反射允许实例化类而不退回到Java反射:
def create[T: TypeTag](map: Map[String, Any]): T = {
// obtain type symbol for the class, it is like Class but for Scala types
val typeSym = typeOf[T].typeSymbol.asClass
// obtain class mirror using runtime mirror for the given classloader
val mirror = runtimeMirror(getClass.getClassLoader) // current class classloader
val cm = mirror.reflectClass(typeSym)
// resolve class constructor using class mirror and
// a constructor declaration on the type symbol
val ctor = typeSym.decl(termNames.CONSTRUCTOR).asMethod
val ctorm = cm.reflectConstructor(cm)
// invoke the constructor
ctorm(<constructor arguments here>).asInstanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)
如果你想创建一个带有重载构造函数的类,它可能需要更多工作 - 你必须从声明列表中选择正确的构造函数,但基本思想是相同的.您可以在此处阅读有关Scala反射的更多信息
| 归档时间: |
|
| 查看次数: |
989 次 |
| 最近记录: |