Zum Inhalt springen
Anjunar/ DOCS

Konstruktoren und Parameter

Konstruktoren erzeugen Instanzen; Methoden und Konstruktoren teilen ResolvedParameter, der Namen, aufgelösten Typ und Annotationen eines Parameters trägt.

Erzeugen

findConstructor und newInstance

findConstructor findet einen öffentlichen Konstruktor der Klasse über seine Parameterklassen, findDeclaredConstructor jeden, private eingeschlossen. newInstance übergibt die Argumente der Reihe nach.

scala
class User(val id: Long, val name: String) val constructor = TypeResolver.resolve(classOf[User]).findConstructor(classOf[Long], classOf[String]) val ada = constructor.newInstance(Long.box(1L), "Ada").asInstanceOf[User] println(ada.name) // Ada
Scala-Primitive sind JVM-Primitive

classOf[Long] ist das primitive long, das der Konstruktor deklariert. Übergib newInstance geboxte Werte wie Long.box(1L).

Parameter

Namen, Typen und Annotationen

Parameternamen kommen aus der Klassendatei. Scala 3 schreibt sie standardmäßig; Java-Klassen brauchen javac -parameters, sonst heißen sie arg0, arg1 und so weiter.

scala
val parameters = TypeResolver.resolve(classOf[User]) .findConstructor(classOf[Long], classOf[String]).parameters parameters.foreach(parameter => println(s"${parameter.name}: ${parameter.parameterType.name}"))
Ausgabe
id: long name: String

parameterType wird gegen die besitzende Klasse aufgelöst; ein Parameter einer generischen Basismethode liest sich in der Unterklasse als konkreter Typ. Bei Methodenparametern enthält annotations auch die desselben Parameters in überschriebenen Methoden.

Konstruktion ohne Argumente

Was Frameworks meistens brauchen

Mapper erzeugen eine leere Instanz und füllen sie über Properties. Dafür braucht es einen öffentlichen Konstruktor ohne Parameter.

scala
def create[T](clazz: Class[T]): T = val constructor = TypeResolver.resolve(clazz).findConstructor() require(constructor != null, s"${clazz.getName} needs a public no-argument constructor") constructor.newInstance().asInstanceOf[T]