Class TypeResolver
- java.lang.Object
-
- com.fasterxml.classmate.TypeResolver
-
- All Implemented Interfaces:
java.io.Serializable
public class TypeResolver extends java.lang.Object implements java.io.Serializable
Object that is used for resolving generic type information of a class so that it is accessible using simple API. Resolved types are also starting point for accessing resolved (generics aware) return and argument types of class members (methods, fields, constructors).Note that resolver instances are stateful in that resolvers cache resolved types for efficiency. Since this is internal state and not directly visible to callers, access to state is fully synchronized so that access from multiple threads is safe.
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected static java.util.HashMap<ClassKey,ResolvedType>
_primitiveTypes
Since number of primitive types is small, and they are frequently needed, let's actually pre-create them for efficient reuse.protected ResolvedTypeCache
_resolvedTypes
Simple cache of types resolved by this resolver.private static ResolvedType[]
NO_TYPES
private static ResolvedObjectType
sJavaLangObject
We will also need to return "unknown" type for cases where type variable binding is not found ('raw' instances of generic types); easiest way is to pre-create type forjava.lang.Object
-
Constructor Summary
Constructors Constructor Description TypeResolver()
Constructs type cache; equivalent to:TypeResolver(ResolvedTypeCache typeCache)
Constructor that specifies type cache to use.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private ResolvedType
_constructType(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
private ResolvedType
_fromAny(ClassStack context, java.lang.reflect.Type mainType, TypeBindings typeBindings)
private ResolvedType
_fromArrayType(ClassStack context, java.lang.reflect.GenericArrayType arrayType, TypeBindings typeBindings)
private ResolvedType
_fromClass(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
private ResolvedType
_fromGenericType(ClassStack context, GenericType<?> generic, TypeBindings typeBindings)
Factory method for resolving given generic type, defined by using sub-class instance ofGenericType
private ResolvedType
_fromParamType(ClassStack context, java.lang.reflect.ParameterizedType ptype, TypeBindings parentBindings)
private ResolvedType
_fromVariable(ClassStack context, java.lang.reflect.TypeVariable<?> variable, TypeBindings typeBindings)
private ResolvedType
_fromWildcard(ClassStack context, java.lang.reflect.WildcardType wildType, TypeBindings typeBindings)
private ResolvedType
_resolveSuperClass(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
NOTE: return type changed in 1.0.1 fromResolvedObjectType
toResolvedType
, since it was found that other types may be returned...private ResolvedType[]
_resolveSuperInterfaces(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
private void
_resolveTypePlaceholders(ResolvedType sourceType, ResolvedType actualType)
Method called to verify that types match; and if there are any placeholders, replace them inactualType
.private boolean
_verifyAndResolve(ResolvedType exp, ResolvedType act)
ResolvedArrayType
arrayType(java.lang.reflect.Type elementType)
Factory method for constructing array type of given element type.static boolean
isSelfReference(ResolvedType type)
Convenience method that can be used to checked whether given resolved type (with erased type ofjava.lang.Object
) is a placeholder for "self-reference"; these are nasty recursive ("self") types needed with some interfacesResolvedType
resolve(TypeBindings typeBindings, java.lang.reflect.Type jdkType)
Factory method for resolving specified JavaType
, givenTypeBindings
needed to resolve any type variables.ResolvedType
resolve(java.lang.reflect.Type type, java.lang.reflect.Type... typeParameters)
Factory method for resolving given base type using specified types as type parameters.ResolvedType
resolveSubtype(ResolvedType supertype, java.lang.Class<?> subtype)
Factory method for constructing sub-classing specified type; class specified as sub-class must be compatible according to basic Java inheritance rules (subtype must properly extend or implement specified supertype).
-
-
-
Field Detail
-
NO_TYPES
private static final ResolvedType[] NO_TYPES
-
sJavaLangObject
private static final ResolvedObjectType sJavaLangObject
We will also need to return "unknown" type for cases where type variable binding is not found ('raw' instances of generic types); easiest way is to pre-create type forjava.lang.Object
-
_primitiveTypes
protected static final java.util.HashMap<ClassKey,ResolvedType> _primitiveTypes
Since number of primitive types is small, and they are frequently needed, let's actually pre-create them for efficient reuse. Same goes for limited number of other "standard" types...
-
_resolvedTypes
protected final ResolvedTypeCache _resolvedTypes
Simple cache of types resolved by this resolver. Caching works because type instances themselves are mostly immutable; and properly synchronized in cases where transient data (raw members) are accessed.
-
-
Constructor Detail
-
TypeResolver
public TypeResolver()
Constructs type cache; equivalent to:TypeResolver(ResolvedTypeCache.lruCache(200));
-
TypeResolver
public TypeResolver(ResolvedTypeCache typeCache)
Constructor that specifies type cache to use.- Parameters:
typeCache
- Cache to use for avoiding repeated resolution of already resolved types- Since:
- 1.4
-
-
Method Detail
-
resolve
public ResolvedType resolve(java.lang.reflect.Type type, java.lang.reflect.Type... typeParameters)
Factory method for resolving given base type using specified types as type parameters. Sample usage would be:ResolvedType type = TypeResolver.resolve(List.class, Integer.class);
which would be equivalent toResolvedType type = TypeResolver.resolve(new GenericType<List<Integer>>() { });
Note that you can mix different types of type parameters, whether already resolved (ResolvedType
), type-erased (Class
) or generic type reference (GenericType
).
-
arrayType
public ResolvedArrayType arrayType(java.lang.reflect.Type elementType)
Factory method for constructing array type of given element type.
-
resolve
public ResolvedType resolve(TypeBindings typeBindings, java.lang.reflect.Type jdkType)
Factory method for resolving specified JavaType
, givenTypeBindings
needed to resolve any type variables.Use of this method is discouraged (use if and only if you really know what you are doing!); but if used, type bindings passed should come from
ResolvedType
instance of declaring class (or interface).NOTE: order of arguments was reversed for 0.8, to avoid problems with overload varargs method.
-
resolveSubtype
public ResolvedType resolveSubtype(ResolvedType supertype, java.lang.Class<?> subtype) throws java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException
Factory method for constructing sub-classing specified type; class specified as sub-class must be compatible according to basic Java inheritance rules (subtype must properly extend or implement specified supertype).A typical use case here is to refine a generic type; for example, given that we have generic type like
List<Integer>
, but we want a more specific implementation type like classArrayList
but with same parameterization (here justInteger
), we could achieve it by:ResolvedType mapType = typeResolver.resolve(List.class, Integer.class); ResolveType concreteMapType = typeResolver.resolveSubType(mapType, ArrayList.class);
(in this case, it would have been simpler to resolve directly; but in some cases we are handled supertype and want to refine it, in which case steps would be the same but separated by other code)Note that this method will fail if extension can not succeed; either because this type is not extendable (sub-classable) -- which is true for primitive and array types -- or because given class is not a subtype of this type. To check whether subtyping could succeed, you can call
ResolvedType.canCreateSubtypes()
to see if supertype can ever be extended.- Parameters:
supertype
- Type to subtype (extend)subtype
- Type-erased sub-class or sub-interface- Returns:
- Resolved subtype
- Throws:
java.lang.IllegalArgumentException
- If this type can be extended in general, but not into specified sub-classjava.lang.UnsupportedOperationException
- If this type can not be sub-classed
-
isSelfReference
public static boolean isSelfReference(ResolvedType type)
Convenience method that can be used to checked whether given resolved type (with erased type ofjava.lang.Object
) is a placeholder for "self-reference"; these are nasty recursive ("self") types needed with some interfaces- Parameters:
type
- Type to check
-
_fromAny
private ResolvedType _fromAny(ClassStack context, java.lang.reflect.Type mainType, TypeBindings typeBindings)
-
_fromClass
private ResolvedType _fromClass(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
-
_fromGenericType
private ResolvedType _fromGenericType(ClassStack context, GenericType<?> generic, TypeBindings typeBindings)
Factory method for resolving given generic type, defined by using sub-class instance ofGenericType
-
_constructType
private ResolvedType _constructType(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
-
_resolveSuperInterfaces
private ResolvedType[] _resolveSuperInterfaces(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
-
_resolveSuperClass
private ResolvedType _resolveSuperClass(ClassStack context, java.lang.Class<?> rawType, TypeBindings typeBindings)
NOTE: return type changed in 1.0.1 fromResolvedObjectType
toResolvedType
, since it was found that other types may be returned...- Returns:
- Usually a
ResolvedObjectType
, but possibly alsoResolvedRecursiveType
-
_fromParamType
private ResolvedType _fromParamType(ClassStack context, java.lang.reflect.ParameterizedType ptype, TypeBindings parentBindings)
-
_fromArrayType
private ResolvedType _fromArrayType(ClassStack context, java.lang.reflect.GenericArrayType arrayType, TypeBindings typeBindings)
-
_fromWildcard
private ResolvedType _fromWildcard(ClassStack context, java.lang.reflect.WildcardType wildType, TypeBindings typeBindings)
-
_fromVariable
private ResolvedType _fromVariable(ClassStack context, java.lang.reflect.TypeVariable<?> variable, TypeBindings typeBindings)
-
_resolveTypePlaceholders
private void _resolveTypePlaceholders(ResolvedType sourceType, ResolvedType actualType) throws java.lang.IllegalArgumentException
Method called to verify that types match; and if there are any placeholders, replace them inactualType
.- Parameters:
sourceType
- Original base type used for specification/refinementactualType
- Base type instance after re-resolving, possibly containing type placeholders- Throws:
java.lang.IllegalArgumentException
-
_verifyAndResolve
private boolean _verifyAndResolve(ResolvedType exp, ResolvedType act)
-
-