Package net.jodah.typetools
Class TypeResolver
java.lang.Object
net.jodah.typetools.TypeResolver
Enhanced type resolution utilities.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static interface
static final class
An unknown type. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic void
Disables the internal caching of resolved TypeVariables.static void
Enables the internal caching of resolved TypeVariables.private static Member
getConstantPoolMethodAt
(Object constantPool, int i) private static int
getConstantPoolSize
(Object constantPool) private static Member
getMemberRef
(Class<?> type) private static Map
<TypeVariable<?>, Type> getTypeVariableMap
(Class<?> targetType, Class<?> functionalInterface) private static boolean
isAutoBoxingMethod
(Method method) private static boolean
private static void
populateLambdaArgs
(Class<?> functionalInterface, Class<?> lambdaType, Map<TypeVariable<?>, Type> map) Populates themap
with variable/argument pairs for thefunctionalInterface
.private static void
populateSuperTypeArgs
(Type[] types, Map<TypeVariable<?>, Type> map, boolean depthFirst) Populates themap
with with variable/argument pairs for the giventypes
.private static void
populateTypeArgs
(ParameterizedType type, Map<TypeVariable<?>, Type> map, boolean depthFirst) Populates themap
with variable/argument pairs for the giventype
.static <T,
S extends T>
TypeTraverses a generic type and replaces all type variables and wildcard types with concrete types (if possible), by using the type information from givencontext
.static Type
Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible).static Type
Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible), by using the type information from givencontext
.private static Type
reify
(Type genericType, Map<TypeVariable<?>, Type> typeVariableTypeMap) private static Type
reify
(Type genericType, Map<TypeVariable<?>, Type> typeVariableMap, Map<ParameterizedType, ReifiedParameterizedType> partial) Works likeresolveRawClass(Type, Class, Class)
but does not stop at raw classes.static Type
resolveBound
(TypeVariable<?> typeVariable) Resolves the first bound for thetypeVariable
, returningUnknown.class
if none can be resolved.static Type
resolveGenericType
(Class<?> type, Type subType) Returns the generictype
using type variable information from thesubType
elsenull
if the generic type cannot be resolved.static <T,
S extends T>
Class<?> resolveRawArgument
(Class<T> type, Class<S> subType) Returns the raw class representing the argument for thetype
using type variable information from thesubType
.static Class
<?> resolveRawArgument
(Type genericType, Class<?> subType) Returns the raw class representing the argument for thegenericType
using type variable information from thesubType
.static <T,
S extends T>
Class<?>[]resolveRawArguments
(Class<T> type, Class<S> subType) Returns an array of raw classes representing arguments for thetype
using type variable information from thesubType
.static Class<?>[]
resolveRawArguments
(Type genericType, Class<?> subType) Returns an array of raw classes representing arguments for thegenericType
using type variable information from thesubType
.static Class
<?> resolveRawClass
(Type genericType, Class<?> subType) Resolves the raw class for thegenericType
, using the type variable information from thesubType
elseTypeResolver.Unknown
if the raw class cannot be resolved.private static Class
<?> resolveRawClass
(Type genericType, Class<?> subType, Class<?> functionalInterface) private static Class
<?> wrapPrimitives
(Class<?> clazz)
-
Field Details
-
TYPE_VARIABLE_CACHE
Cache of type variable/argument pairs -
CACHE_ENABLED
private static volatile boolean CACHE_ENABLED -
RESOLVES_LAMBDAS
private static boolean RESOLVES_LAMBDAS -
JAVA_LANG_ACCESS
-
GET_CONSTANT_POOL
-
GET_CONSTANT_POOL_SIZE
-
GET_CONSTANT_POOL_METHOD_AT
-
OBJECT_METHODS
-
PRIMITIVE_WRAPPERS
-
JAVA_VERSION
-
-
Constructor Details
-
TypeResolver
private TypeResolver()
-
-
Method Details
-
enableCache
public static void enableCache()Enables the internal caching of resolved TypeVariables. -
disableCache
public static void disableCache()Disables the internal caching of resolved TypeVariables. -
resolveRawArgument
Returns the raw class representing the argument for thetype
using type variable information from thesubType
. If no arguments can be resolved thenUnknown.class
is returned.- Parameters:
type
- to resolve argument forsubType
- to extract type variable information from- Returns:
- argument for
type
elseTypeResolver.Unknown
.class if no type arguments are declared - Throws:
IllegalArgumentException
- if more or less than one argument is resolved for thetype
-
resolveRawArgument
Returns the raw class representing the argument for thegenericType
using type variable information from thesubType
. IfgenericType
is an instance of class, thengenericType
is returned. If no arguments can be resolved thenUnknown.class
is returned.- Parameters:
genericType
- to resolve argument forsubType
- to extract type variable information from- Returns:
- argument for
genericType
elseTypeResolver.Unknown
.class if no type arguments are declared - Throws:
IllegalArgumentException
- if more or less than one argument is resolved for thegenericType
-
resolveRawArguments
Returns an array of raw classes representing arguments for thetype
using type variable information from thesubType
. Arguments fortype
that cannot be resolved are returned asUnknown.class
. If no arguments can be resolved thennull
is returned.- Parameters:
type
- to resolve arguments forsubType
- to extract type variable information from- Returns:
- array of raw classes representing arguments for the
type
elsenull
if no type arguments are declared
-
reify
Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible), by using the type information from givencontext
. A convenience method which largely works the same asreify(Type, Class)
, but first resolves the generic type oftype
.- Parameters:
type
- the class whose generic type to traversecontext
- the class that serves as starting point to resolve replacements of type variables- Returns:
- a type that is structurally the same as
type
, except that type variables and wildcard types have been replaced with concrete types - Throws:
UnsupportedOperationException
- iftype
(or a type that it references) is not an instance of one of the following types:Class
,TypeVariable
,WildcardType
,ParameterizedType
,GenericArrayType
.UnsupportedOperationException
- iftype
(or a type that it references) is aWildcardType
that does not have exactly one upper bound, or does not have no lower bounds.UnsupportedOperationException
- iftype
(or a type that it references) is aGenericArrayType
whose generic component type cannot be reified to an instance ofClass
.
-
reify
Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible), by using the type information from givencontext
. Generic types used as input to this method are commonly obtained using reflection, e.g. viaField.getGenericType()
,Method.getGenericReturnType()
,Method.getGenericParameterTypes()
. Example:
Reifying the generic return type of the methodclass A<T> { public T something; public Optional<List<T>> compute() { ... } } class B extends A<Number> { public <? extends Collection<List<?>>> collect() { ... } }
compute
withB.class
ascontext
will yield the parameterized typeOptional<List<Number>>
. Note that not the raw type (Optional
is returned, but the input type is reified recursively. Reifying the generic type of the fieldsomething
withB.class
ascontext
will yieldNumber.class
. Note that type variables with no explicit upper bound are reified toObject
, andUnknown.class
is never returned.- Parameters:
type
- the generic type to traversecontext
- the class that serves as starting point to resolve replacements of type variables- Returns:
- a type that is structurally the same as
type
, except that type variables and wildcard types have been replaced with concrete types - Throws:
UnsupportedOperationException
- iftype
(or a type that it references) is not an instance of one of the following types:Class
,TypeVariable
,WildcardType
,ParameterizedType
,GenericArrayType
.UnsupportedOperationException
- iftype
(or a type that it references) is aWildcardType
that does not have exactly one upper bound, or does not have no lower bounds.UnsupportedOperationException
- iftype
(or a type that it references) is aGenericArrayType
whose generic component type cannot be reified to an instance ofClass
.
-
reify
Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible). A convenience wrapper aroundreify(Type, Class)
, for when no context is needed/available. Generic types used as input to this method are commonly obtained using reflection, e.g. viaField.getGenericType()
,Method.getGenericReturnType()
,Method.getGenericParameterTypes()
. Example:
Reifying the generic return type of the methodclass X { public List<? extends Collection<List<? extends Number>>> collectList() { ... } public Set<?> collectSet() { ... } }
collectList
will yield the parameterized typeList<Collection<List<Number>>>
. Reifying the generic return type of the methodcollectSet
will yield the parameterized typeSet<Object>
, since there is no explicit upper bound for the wildcard type given.- Parameters:
type
- the generic type to traverse- Returns:
- a type that is structurally the same as
type
, except that type variables and wildcard types have been replaced with concrete types - Throws:
UnsupportedOperationException
- iftype
(or a type that it references) is not an instance of one of the following types:Class
,TypeVariable
,WildcardType
,ParameterizedType
,GenericArrayType
.UnsupportedOperationException
- iftype
(or a type that it references) is aWildcardType
that does not have exactly one upper bound, or does not have no lower bounds.UnsupportedOperationException
- iftype
(or a type that it references) is aGenericArrayType
whose generic component type cannot be reified to an instance ofClass
.
-
resolveRawArguments
Returns an array of raw classes representing arguments for thegenericType
using type variable information from thesubType
. Arguments forgenericType
that cannot be resolved are returned asUnknown.class
. If no arguments can be resolved thennull
is returned.- Parameters:
genericType
- to resolve arguments forsubType
- to extract type variable information from- Returns:
- array of raw classes representing arguments for the
genericType
elsenull
if no type arguments are declared
-
resolveGenericType
Returns the generictype
using type variable information from thesubType
elsenull
if the generic type cannot be resolved.- Parameters:
type
- to resolve generic type forsubType
- to extract type variable information from- Returns:
- generic
type
elsenull
if it cannot be resolved
-
resolveRawClass
Resolves the raw class for thegenericType
, using the type variable information from thesubType
elseTypeResolver.Unknown
if the raw class cannot be resolved.- Parameters:
genericType
- to resolve raw class forsubType
- to extract type variable information from- Returns:
- raw class for the
genericType
elseTypeResolver.Unknown
if it cannot be resolved
-
resolveRawClass
-
reify
-
reify
private static Type reify(Type genericType, Map<TypeVariable<?>, Type> typeVariableMap, Map<ParameterizedType, ReifiedParameterizedType> partial) Works likeresolveRawClass(Type, Class, Class)
but does not stop at raw classes. Instead, traverses referenced types.- Parameters:
partial
- contains a mapping of generic types to reified types. A value ofnull
inside aReifiedParameterizedType
instance means that this type is currently being reified.
-
getTypeVariableMap
private static Map<TypeVariable<?>,Type> getTypeVariableMap(Class<?> targetType, Class<?> functionalInterface) -
populateSuperTypeArgs
private static void populateSuperTypeArgs(Type[] types, Map<TypeVariable<?>, Type> map, boolean depthFirst) Populates themap
with with variable/argument pairs for the giventypes
. -
populateTypeArgs
private static void populateTypeArgs(ParameterizedType type, Map<TypeVariable<?>, Type> map, boolean depthFirst) Populates themap
with variable/argument pairs for the giventype
. -
resolveBound
Resolves the first bound for thetypeVariable
, returningUnknown.class
if none can be resolved. -
populateLambdaArgs
private static void populateLambdaArgs(Class<?> functionalInterface, Class<?> lambdaType, Map<TypeVariable<?>, Type> map) Populates themap
with variable/argument pairs for thefunctionalInterface
. -
isDefaultMethod
-
getMemberRef
-
isAutoBoxingMethod
-
wrapPrimitives
-
getConstantPoolSize
-
getConstantPoolMethodAt
-