2009-10-19 11 views
17

uczę Scala i nie można dowiedzieć się, jak to zrobić:Scala: ustawić wartość pola refleksyjnie od nazwy pola

Robię mapowania między obiektami Scala i google podmioty AppEngine, więc jeśli mogę mieć klasę takiego:

muszę utworzyć wystąpienie tej klasy w Javie i dostanie terenie przez jego nazwę, a następnie wykonaj field.set(object, value) ale nie mogę znaleźć, jak to zrobić w Scala.

Nie mogę używać odbicia w Javie, ponieważ pola Studentów są postrzegane jako prywatne, a pole.set powoduje błąd z tego powodu.

Dzięki

Odpowiedz

36

Scala zamienia "zmienna" na prywatnym polu, jeden getter i setter jeden. Aby więc uzyskać/ustawić var ​​przez identyfikację go za pomocą String, musisz użyć Java Reflections, aby znaleźć metody getter/setter. Poniżej znajduje się fragment kodu, który to robi. Należy pamiętać, że ten kod działa pod Scala 2.8.0, a obsługa powielonych nazw metod i błędów nie istnieje.

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

Dzięki! to było naprawdę pomocne, brałem część twojego kodu i działałem dobrze w Scala 2.7.6 – Damian

+0

Możesz także bezpośrednio pobrać metodę według nazwy, jeśli używasz getClass.getDeclaredMethod, jeśli znasz wcześniej typy parametrów metody! –

+0

Dlaczego jest lepszy niż ustawienie field.setAccessible (true)? – Yael

Powiązane problemy