2009-10-19 12 views
17

estoy aprendiendo Scala y no puedo encontrar la manera de hacer esto:Scala: establecer un valor de campo de nombre de campo reflexivamente

estoy haciendo un asignador entre objetos Scala y Google App Engine entidades, por lo que si i tener una clase como esta:

es necesario crear una instancia de esa clase, en java que obtendría el campo por su nombre y luego hacer field.set(object, value) pero no puedo encontrar la manera de hacerlo en Scala.

No puedo usar el reflejo de java ya que los campos de Estudiante se ven como privados y field.set arroja un error debido a eso.

Gracias

Respuesta

36

Scala gira "var" en un campo privado, un getter y setter uno. Entonces, para obtener/establecer una var identificándola usando un String, necesita usar la reflexión de Java para encontrar los métodos getter/setter. A continuación se muestra un fragmento de código que hace eso. Tenga en cuenta que este código se ejecuta bajo Scala 2.8.0 y no existen manejos de nombres de métodos duplicados y errores.

class Student { 
    var id: Long = _ 
    var name: String = _ 
} 

implicit def reflector(ref: AnyRef) = new { 
    def getV(name: String): Any = ref.getClass.getMethods.find(_.getName == name).get.invoke(ref) 
    def setV(name: String, value: Any): Unit = ref.getClass.getMethods.find(_.getName == name + "_$eq").get.invoke(ref, value.asInstanceOf[AnyRef]) 
} 

val s = new Student 
s.setV("name", "Walter") 
println(s.getV("name")) // prints "Walter" 
s.setV("id", 1234) 
println(s.getV("id")) // prints "1234" 
+0

Gracias! eso fue realmente útil, tomé parte de su código y funcionó bien en Scala 2.7.6 – Damian

+0

También puede buscar directamente el método por nombre si usa getClass.getDeclaredMethod si conoce de antemano los tipos de parámetros del método. –

+0

¿Por qué es mejor que establecer field.setAccessible (true)? – Yael

Cuestiones relacionadas