Skip to content
Anjunar/ DOCS

Class loaders

A ReflectClassLoader keeps its own descriptors and factories, asks an optional parent next, and falls back to the global registry last.

Subtypes

Ask by name

Registered descriptors carry their base types, so the loader answers subtype questions without runtime classes.

loader.isAssignableFrom("demo.Dog", "demo.Animal")
true
loader.getSubTypes("demo.Animal").map(_.simpleName).distinct
List(Animal, Dog, Cat)
loader.createInstanceAs[Dog]("demo.Dog").map(_.name)
Some(Milo)
scala
val loader = ReflectClassLoader.create() loader.register[Animal](ReflectMacros.reflect[Animal]) loader.register[Dog](ReflectMacros.reflect[Dog], () => Dog("Milo")) loader.isAssignableFrom("demo.Dog", "demo.Animal") loader.getSubTypes("demo.Animal")
getSubTypes includes the type itself

Every type counts as its own subtype, and a type found both locally and in the global registry can appear twice. Deduplicate by typeName when you list the results.

Lookup order

Local, parent, global

loadClass asks the loader's own entries, then its parent, then the global ReflectRegistry. register publishes the descriptor to the global registry as well.

child.loadClass("demo.Person").isDefined
true
child.createInstanceAs[Person]("demo.Person")
Some(Person(Ada,37))
ReflectRegistry.contains("demo.Person")
true
scala
val parent = ReflectClassLoader.create() val child = ReflectClassLoader.createWithParent(parent) parent.register[Person](ReflectMacros.reflect[Person], () => Person("Ada", 37)) child.createInstanceAs[Person]("demo.Person") // the parent's factory
Not an isolation boundary

Because registrations reach the global registry, every loader and the registry itself can see them. Use loaders for lookup order and local factories, not to hide types from each other.

Resources

Text next to the types

ReflectClassLoaderWithResources adds a store for named strings, such as a schema or a template that belongs to the registered types.

loader.getResource("person.schema.json")
Some({"title":"Person"})
scala
val loader = ReflectClassLoaderWithResources() loader.addResource("person.schema.json", """{"title":"Person"}""") loader.getResource("person.schema.json")