我想弄清楚如何用反射实例化一个案例类对象。是否有任何支持?我最接近的是查看 scala.reflect.Invocation,但这似乎更适合执行作为对象一部分的方法。
case class MyClass(id:Long, name:String)
def instantiate[T](className:String)(args:Any*) : T = { //your code here }
接近我正在寻找的 API。
任何帮助,将不胜感激。
最佳答案
scala> case class Foo(id:Long, name:String)
defined class Foo
scala> val constructor = classOf[Foo].getConstructors()(0)
constructor: java.lang.reflect.Constructor[_] = public Foo(long,java.lang.String)
scala> val args = Array[AnyRef](new java.lang.Integer(1), "Foobar")
args: Array[AnyRef] = Array(1, Foobar)
scala> val instance = constructor.newInstance(args:_*).asInstanceOf[Foo]
instance: Foo = Foo(1,Foobar)
scala> instance.id
res12: Long = 1
scala> instance.name
res13: String = Foobar
scala> instance.getClass
res14: java.lang.Class[_] = class Foo
目前 Scala 中没有太多反射支持。但是您可以退回到 Java 反射 API。但是有一些障碍:
Array[AnyRef]
并将您的“原始类型”装入包装类( java.lang.Integer, java.lang.Character, java.lang.Double, ...
)newInstance(Object ... args)
获取 Object
的可变参数数组,所以你应该给类型推断器一个提示 :_*
newInstance(...)
返回 Object
所以你必须用 asInstanceOf[T]
把它扔回去离你最近的
instantiate
功能是这样的:def instantiate(clazz: java.lang.Class[_])(args:AnyRef*): AnyRef = {
val constructor = clazz.getConstructors()(0)
return constructor.newInstance(args:_*).asInstanceOf[AnyRef]
}
val instance = instantiate(classOf[MyClass])(new java.lang.Integer(42), "foo")
println(instance) // prints: MyClass(42,foo)
println(instance.getClass) // prints: class MyClass
您无法从泛型类型获取 get 类。 Java 删除它(类型删除)。
编辑:2012 年 9 月 20 日
三年过去了,
instantiate
可以改进方法以返回正确类型的对象。def instantiate[T](clazz: java.lang.Class[T])(args:AnyRef*): T = {
val constructor = clazz.getConstructors()(0)
return constructor.newInstance(args:_*).asInstanceOf[T]
}
见 http://www.nabble.com/How-do-I-get-the-class-of-a-Generic--td20873455.html
关于reflection - 使用构造函数参数通过反射实例化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1641104/