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
Actualmente no hay mucho soporte de reflexión en Scala. Pero puede recurrir a la API de reflexión de Java. Sin embargo, hay algunos obstáculos:
Tienes que crear un Array[AnyRef]
y la caja sus "tipos primitivos" en las clases de envoltura (java.lang.Integer, java.lang.Character, java.lang.Double, ...
)
newInstance(Object ... args)
Obtiene una matriz varargs de Object
, por lo que debe dar el tipo inferer una pista con :_*
newInstance(...)
devuelve un Object
por lo que tienen que desechar de nuevo con asInstanceOf[T]
Lo más cerca que podía llegar a su función instantiate
es la siguiente:
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
no se puede conseguir la clase recibe de un tipo genérico. Java lo borra (escribe borrado).
Editar: 20 Septiembre 2012
Tres años después, el método instantiate
se puede mejorar para devolver un objeto correctamente escrito.
Ver http://www.nabble.com/How-do-I-get-the-class-of-a-Generic--td20873455.html
La reflexión involucrado aquí no tiene nada que ver con las clases de caso en concreto. Solo necesitas un poco de reflexión para encasillar los args. Si estoy equivocado, ¿pueden dar más detalles? – HRJ
Tiene razón, excepto que parte del objetivo es poder escribir clases de casos simples y luego usar un método como este para instanciarlos/modificarlos. – justin