Zum Inhalt springen
Anjunar/ DOCS

Companions und Klassenpfad

Zwei Helfer rund um Typen: das Companion-Objekt einer Scala-Klasse und ein Annotationsindex über ein Paket.

Companions

Von der Klasse zu ihrem Objekt

companionClass findet die Klasse Name$, companionInstance ihre MODULE$-Instanz, geprüft gegen den erwarteten Typ. Beide geben null zurück, wenn es keine gibt.

scala
class Service object Service val companionClass = TypeResolver.companionClass(classOf[Service]) val companion = TypeResolver.companionInstance[Service.type](classOf[Service]) println(companionClass.getName) // Service$ println(companion eq Service) // true

So findet json-mapper das Schema einer Entity: den Companion, der SchemaProvider implementiert. Weil companionInstance den Typ prüft, kommt ein Companion anderer Art als null zurück, statt später zu scheitern.

scala
val provider = TypeResolver.companionInstance[SchemaProvider[?]](classOf[Article]) if provider != null then println(provider.schema.properties.keys.mkString(", "))
Klassenpfad

Ein Annotationsindex

process lädt jede Klasse unterhalb eines Paketpräfixes und indexiert die Annotationen an Klassen, Konstruktoren, deren Parametern, Feldern und Methoden. findAnnotation liefert jede Annotation mit dem Element, das sie trägt.

scala
import com.anjunar.scala.universe.ClassPathResolver val classes = ClassPathResolver.process("com.example", Thread.currentThread().getContextClassLoader) ClassPathResolver.findAnnotation(classOf[jakarta.inject.Singleton]) .foreach(found => println(found.target))
In einem CDI-Container

ClassPathResolver ist auch eine CDI-Extension. In META-INF/services registriert, sammelt sie jeden Typ, den der Container entdeckt, und baut nach dem Deployment denselben Index.

text
# META-INF/services/jakarta.enterprise.inject.spi.Extension com.anjunar.scala.universe.ClassPathResolver
Erst indexieren

findAnnotation wirft NoSuchElementException für eine Annotation, die nie indexiert wurde. Führe process aus oder lass die CDI-Extension laufen, bevor du nachschlägst.