Zum Inhalt springen
Anjunar/ DOCS

Felder

Felder gibt es in zwei Mengen: an der Klasse deklariert und alles, was über die Hierarchie sichtbar ist. Jedes kennt seinen aufgelösten Typ und liest und schreibt ohne Zugriffsprüfung.

Suche

findField und findDeclaredField

findField sucht in der ganzen Hierarchie, private Felder eingeschlossen; findDeclaredField nur in der Klasse selbst. Beide geben null zurück, wenn nichts passt.

scala
class User(private var id: Long, val name: String) val user = TypeResolver.resolve(classOf[User]) val name = user.findField("name") println(name.fieldType.fullName) // java.lang.String println(user.fields.map(_.name).mkString(", ")) // id, name
Scala

Welche Parameter zu Feldern werden

Ein val- oder var-Parameter wird immer zu einem privaten Feld mit Accessor-Methoden. Ein einfacher Konstruktorparameter wird nur zum Feld, wenn die Klasse ihn außerhalb des Konstruktors verwendet.

class A(val x: Int)
Feld x und Methode x().
class A(var x: Int)
Feld x, Methoden x() und x_$eq(int).
class A(x: Int) { def twice = x * 2 }
Feld x, weil twice es liest.
class A(x: Int) extends B(x)
Kein Feld; x erreicht nur den Superkonstruktor.
Verdecken

Das spezifischste Feld gewinnt

Deklariert eine Unterklasse ein Feld mit dem Namen eines Oberklassen-Felds, listet fields nur das der Unterklasse. Die verdeckten bleiben über hidden erreichbar, und ihre Annotationen fließen in annotations ein.

java
public class Base { @Deprecated protected String label = "base"; } public class Child extends Base { private String label = "child"; }
scala
val field = TypeResolver.resolve(classOf[Child]).findField("label") println(field.owner.name) // Child println(field.hidden.map(_.owner.name).mkString(", ")) // Base println(field.findAnnotation(classOf[Deprecated]) != null) // true
Zugriff

get und set

Beide machen das Feld zuerst zugänglich; private Felder funktionieren ohne Zusatzschritte. Ein finales Feld lässt sich lesen, sein Wert sollte aber nicht geschrieben werden.

scala
val ada = new User(1L, "Ada") val id = TypeResolver.resolve(classOf[User]).findDeclaredField("id") id.set(ada, 2L) println(id.get(ada)) // 2
Felder umgehen deine Logik

Ein Feld zu schreiben überspringt den Setter und alles darin. Für Werte, die durch Validierung oder Events gehen, nimm eine Property (Bean oder annotiert) und ihren Setter.