Skip to content
Anjunar/ DOCS

Hierarchy and subtypes

A ResolvedClass knows every supertype, each resolved against the type you started from. That is the ground everything inherited stands on.

Order

The type, its interfaces, then upwards

hierarchy starts with the type itself, then its interfaces, then the superclass with its interfaces, up to but not including Object.

scala
package example trait Named { def name: String } abstract class Repository[E] extends Named class UserRepository extends Repository[User] { def name = "users" } TypeResolver.resolve(classOf[UserRepository]).hierarchy .foreach(entry => println(entry.underlying.getTypeName))
Output
example.UserRepository example.Repository<example.User> example.Named
Resolved, not declared

Repository appears as Repository<User>, not as Repository<E>. Every member found through this entry is typed accordingly.

Checks

Subtypes with generics

<:< compares full types, not only raw classes. Primitive types are wrapped first, so int and Integer behave alike.

scala
val users = TypeResolver.resolve(classOf[UserRepository]) val repository = TypeResolver.resolve(classOf[Repository[?]]) val items = users.findField("items").fieldType val collection = TypeResolver.resolve(classOf[java.util.Collection[?]]) println(users <:< repository) // true println(items <:< collection) // true
Inheritance

What the hierarchy feeds

Four collections walk the hierarchy; their declared counterparts stay on the class itself.

fields · declaredFields
All visible fields, hidden ones removed · the class's own.
methods · declaredMethods
All methods, overridden ones removed · the class's own.
constructors · declaredConstructors
Constructors of every class in the hierarchy · the class's own.
annotations · declaredAnnotations
Annotations of every supertype · the class's own.
constructors crosses class boundaries

constructors includes the superclasses' constructors, which cannot create the subclass. Use declaredConstructors or findConstructor to create instances.