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 не так много поддержки отражений. Но вы можете вернуться к API Java Reflection. Но есть некоторые препятствия:
Вы должны создать Array[AnyRef]
и указать свои "примитивные типы" в классах-оболочках (java.lang.Integer, java.lang.Character, java.lang.Double, ...
)
newInstance(Object ... args)
получает массив varargs, равный Object
, поэтому вы должны дать подсказке для типа Infiner команду :_*
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 стирает его (стирание типа).
Редактировать: 20 сентября 2012
Через три года метод 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