Resolving types
Every entry starts at TypeResolver.resolve. It takes any java.lang.reflect.Type, a plain class as well as a parameterized type or a type variable, and returns a ResolvedClass.
Entry
A class in, a model out
name and fullName come from the raw class. The model itself stays lazy: members, hierarchy and annotations are read on first access.
scala
import com.anjunar.scala.universe.TypeResolver
val resolved = TypeResolver.resolve(classOf[String])
println(resolved.name) // String
println(resolved.fullName) // java.lang.String
println(resolved.raw) // class java.lang.String
Parameterized types
underlying keeps what raw forgets
A ResolvedClass for List[User] has two views: underlying, the full ParameterizedType, and raw, the erased java.util.List. typeArguments are ResolvedClasses themselves.
scala
val field = TypeResolver.resolve(classOf[UserRepository]).findField("items")
val list = field.fieldType
println(list.underlying.getTypeName) // java.util.List<example.User>
println(list.raw) // interface java.util.List
println(list.typeArguments.map(_.name).mkString(", ")) // User
Any Type
Variables and wildcards
rawType erases any Type to a class: a parameterized type to its raw type, a wildcard to its upper bound. Resolving through a concrete subclass is what replaces type variables with real types.
- resolve(aType: Type): ResolvedClass
- The cached model of a type.
- rawType(aType: Type): Class[?]
- The erased class of any Type.
- ResolvedClass.underlying: Type
- The Type this model was resolved from.
- ResolvedClass.raw: Class[?]
- The erased class behind it.
- ResolvedClass.typeArguments: Array[ResolvedClass]
- The actual arguments; empty for a plain class.