Package net.jodah.typetools
Class TypeResolver
- java.lang.Object
-
- net.jodah.typetools.TypeResolver
-
public final class TypeResolver extends java.lang.ObjectEnhanced type resolution utilities.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static interfaceTypeResolver.AccessMakerstatic classTypeResolver.UnknownAn unknown type.
-
Field Summary
Fields Modifier and Type Field Description private static booleanCACHE_ENABLEDprivate static java.lang.reflect.MethodGET_CONSTANT_POOLprivate static java.lang.reflect.MethodGET_CONSTANT_POOL_METHOD_ATprivate static java.lang.reflect.MethodGET_CONSTANT_POOL_SIZEprivate static java.lang.ObjectJAVA_LANG_ACCESSprivate static java.lang.DoubleJAVA_VERSIONprivate static java.util.Map<java.lang.String,java.lang.reflect.Method>OBJECT_METHODSprivate static java.util.Map<java.lang.Class<?>,java.lang.Class<?>>PRIMITIVE_WRAPPERSprivate static booleanRESOLVES_LAMBDASprivate static java.util.Map<java.lang.Class<?>,java.lang.ref.Reference<java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type>>>TYPE_VARIABLE_CACHECache of type variable/argument pairs
-
Constructor Summary
Constructors Modifier Constructor Description privateTypeResolver()
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static voiddisableCache()Disables the internal caching of resolved TypeVariables.static voidenableCache()Enables the internal caching of resolved TypeVariables.private static java.lang.reflect.MembergetConstantPoolMethodAt(java.lang.Object constantPool, int i)private static intgetConstantPoolSize(java.lang.Object constantPool)private static java.lang.reflect.MembergetMemberRef(java.lang.Class<?> type)private static java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type>getTypeVariableMap(java.lang.Class<?> targetType, java.lang.Class<?> functionalInterface)private static booleanisAutoBoxingMethod(java.lang.reflect.Method method)private static booleanisDefaultMethod(java.lang.reflect.Method m)private static voidpopulateLambdaArgs(java.lang.Class<?> functionalInterface, java.lang.Class<?> lambdaType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map)Populates themapwith variable/argument pairs for thefunctionalInterface.private static voidpopulateSuperTypeArgs(java.lang.reflect.Type[] types, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map, boolean depthFirst)Populates themapwith with variable/argument pairs for the giventypes.private static voidpopulateTypeArgs(java.lang.reflect.ParameterizedType type, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map, boolean depthFirst)Populates themapwith variable/argument pairs for the giventype.static <T,S extends T>
java.lang.reflect.Typereify(java.lang.Class<T> type, java.lang.Class<S> context)Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible), by using the type information from givencontext.static java.lang.reflect.Typereify(java.lang.reflect.Type type)Traverses a generic type and replaces all type variables and wildcard types with concrete types (if possible).static java.lang.reflect.Typereify(java.lang.reflect.Type type, java.lang.Class<?> context)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 java.lang.reflect.Typereify(java.lang.reflect.Type genericType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> typeVariableTypeMap)private static java.lang.reflect.Typereify(java.lang.reflect.Type genericType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> typeVariableMap, java.util.Map<java.lang.reflect.ParameterizedType,ReifiedParameterizedType> partial)Works likeresolveRawClass(Type, Class, Class)but does not stop at raw classes.static java.lang.reflect.TyperesolveBound(java.lang.reflect.TypeVariable<?> typeVariable)Resolves the first bound for thetypeVariable, returningUnknown.classif none can be resolved.static java.lang.reflect.TyperesolveGenericType(java.lang.Class<?> type, java.lang.reflect.Type subType)Returns the generictypeusing type variable information from thesubTypeelsenullif the generic type cannot be resolved.static <T,S extends T>
java.lang.Class<?>resolveRawArgument(java.lang.Class<T> type, java.lang.Class<S> subType)Returns the raw class representing the argument for thetypeusing type variable information from thesubType.static java.lang.Class<?>resolveRawArgument(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Returns the raw class representing the argument for thegenericTypeusing type variable information from thesubType.static <T,S extends T>
java.lang.Class<?>[]resolveRawArguments(java.lang.Class<T> type, java.lang.Class<S> subType)Returns an array of raw classes representing arguments for thetypeusing type variable information from thesubType.static java.lang.Class<?>[]resolveRawArguments(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Returns an array of raw classes representing arguments for thegenericTypeusing type variable information from thesubType.static java.lang.Class<?>resolveRawClass(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Resolves the raw class for thegenericType, using the type variable information from thesubTypeelseTypeResolver.Unknownif the raw class cannot be resolved.private static java.lang.Class<?>resolveRawClass(java.lang.reflect.Type genericType, java.lang.Class<?> subType, java.lang.Class<?> functionalInterface)private static java.lang.Class<?>wrapPrimitives(java.lang.Class<?> clazz)
-
-
-
Field Detail
-
TYPE_VARIABLE_CACHE
private static final java.util.Map<java.lang.Class<?>,java.lang.ref.Reference<java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type>>> 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
private static java.lang.Object JAVA_LANG_ACCESS
-
GET_CONSTANT_POOL
private static java.lang.reflect.Method GET_CONSTANT_POOL
-
GET_CONSTANT_POOL_SIZE
private static java.lang.reflect.Method GET_CONSTANT_POOL_SIZE
-
GET_CONSTANT_POOL_METHOD_AT
private static java.lang.reflect.Method GET_CONSTANT_POOL_METHOD_AT
-
OBJECT_METHODS
private static final java.util.Map<java.lang.String,java.lang.reflect.Method> OBJECT_METHODS
-
PRIMITIVE_WRAPPERS
private static final java.util.Map<java.lang.Class<?>,java.lang.Class<?>> PRIMITIVE_WRAPPERS
-
JAVA_VERSION
private static final java.lang.Double JAVA_VERSION
-
-
Method Detail
-
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
public static <T,S extends T> java.lang.Class<?> resolveRawArgument(java.lang.Class<T> type, java.lang.Class<S> subType)Returns the raw class representing the argument for thetypeusing type variable information from thesubType. If no arguments can be resolved thenUnknown.classis returned.- Parameters:
type- to resolve argument forsubType- to extract type variable information from- Returns:
- argument for
typeelseTypeResolver.Unknown.class if no type arguments are declared - Throws:
java.lang.IllegalArgumentException- if more or less than one argument is resolved for thetype
-
resolveRawArgument
public static java.lang.Class<?> resolveRawArgument(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Returns the raw class representing the argument for thegenericTypeusing type variable information from thesubType. IfgenericTypeis an instance of class, thengenericTypeis returned. If no arguments can be resolved thenUnknown.classis returned.- Parameters:
genericType- to resolve argument forsubType- to extract type variable information from- Returns:
- argument for
genericTypeelseTypeResolver.Unknown.class if no type arguments are declared - Throws:
java.lang.IllegalArgumentException- if more or less than one argument is resolved for thegenericType
-
resolveRawArguments
public static <T,S extends T> java.lang.Class<?>[] resolveRawArguments(java.lang.Class<T> type, java.lang.Class<S> subType)Returns an array of raw classes representing arguments for thetypeusing type variable information from thesubType. Arguments fortypethat cannot be resolved are returned asUnknown.class. If no arguments can be resolved thennullis returned.- Parameters:
type- to resolve arguments forsubType- to extract type variable information from- Returns:
- array of raw classes representing arguments for the
typeelsenullif no type arguments are declared
-
reify
public static <T,S extends T> java.lang.reflect.Type reify(java.lang.Class<T> type, java.lang.Class<S> context)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:
java.lang.UnsupportedOperationException- iftype(or a type that it references) is not an instance of one of the following types:Class,TypeVariable,WildcardType,ParameterizedType,GenericArrayType.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aWildcardTypethat does not have exactly one upper bound, or does not have no lower bounds.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aGenericArrayTypewhose generic component type cannot be reified to an instance ofClass.
-
reify
public static java.lang.reflect.Type reify(java.lang.reflect.Type type, java.lang.Class<?> context)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() { ... } }computewithB.classascontextwill yield the parameterized typeOptional<List<Number>>. Note that not the raw type (Optionalis returned, but the input type is reified recursively. Reifying the generic type of the fieldsomethingwithB.classascontextwill yieldNumber.class. Note that type variables with no explicit upper bound are reified toObject, andUnknown.classis 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:
java.lang.UnsupportedOperationException- iftype(or a type that it references) is not an instance of one of the following types:Class,TypeVariable,WildcardType,ParameterizedType,GenericArrayType.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aWildcardTypethat does not have exactly one upper bound, or does not have no lower bounds.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aGenericArrayTypewhose generic component type cannot be reified to an instance ofClass.
-
reify
public static java.lang.reflect.Type reify(java.lang.reflect.Type type)
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() { ... } }collectListwill yield the parameterized typeList<Collection<List<Number>>>. Reifying the generic return type of the methodcollectSetwill 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:
java.lang.UnsupportedOperationException- iftype(or a type that it references) is not an instance of one of the following types:Class,TypeVariable,WildcardType,ParameterizedType,GenericArrayType.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aWildcardTypethat does not have exactly one upper bound, or does not have no lower bounds.java.lang.UnsupportedOperationException- iftype(or a type that it references) is aGenericArrayTypewhose generic component type cannot be reified to an instance ofClass.
-
resolveRawArguments
public static java.lang.Class<?>[] resolveRawArguments(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Returns an array of raw classes representing arguments for thegenericTypeusing type variable information from thesubType. Arguments forgenericTypethat cannot be resolved are returned asUnknown.class. If no arguments can be resolved thennullis returned.- Parameters:
genericType- to resolve arguments forsubType- to extract type variable information from- Returns:
- array of raw classes representing arguments for the
genericTypeelsenullif no type arguments are declared
-
resolveGenericType
public static java.lang.reflect.Type resolveGenericType(java.lang.Class<?> type, java.lang.reflect.Type subType)Returns the generictypeusing type variable information from thesubTypeelsenullif the generic type cannot be resolved.- Parameters:
type- to resolve generic type forsubType- to extract type variable information from- Returns:
- generic
typeelsenullif it cannot be resolved
-
resolveRawClass
public static java.lang.Class<?> resolveRawClass(java.lang.reflect.Type genericType, java.lang.Class<?> subType)Resolves the raw class for thegenericType, using the type variable information from thesubTypeelseTypeResolver.Unknownif the raw class cannot be resolved.- Parameters:
genericType- to resolve raw class forsubType- to extract type variable information from- Returns:
- raw class for the
genericTypeelseTypeResolver.Unknownif it cannot be resolved
-
resolveRawClass
private static java.lang.Class<?> resolveRawClass(java.lang.reflect.Type genericType, java.lang.Class<?> subType, java.lang.Class<?> functionalInterface)
-
reify
private static java.lang.reflect.Type reify(java.lang.reflect.Type genericType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> typeVariableTypeMap)
-
reify
private static java.lang.reflect.Type reify(java.lang.reflect.Type genericType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> typeVariableMap, java.util.Map<java.lang.reflect.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 ofnullinside aReifiedParameterizedTypeinstance means that this type is currently being reified.
-
getTypeVariableMap
private static java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> getTypeVariableMap(java.lang.Class<?> targetType, java.lang.Class<?> functionalInterface)
-
populateSuperTypeArgs
private static void populateSuperTypeArgs(java.lang.reflect.Type[] types, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map, boolean depthFirst)Populates themapwith with variable/argument pairs for the giventypes.
-
populateTypeArgs
private static void populateTypeArgs(java.lang.reflect.ParameterizedType type, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map, boolean depthFirst)Populates themapwith variable/argument pairs for the giventype.
-
resolveBound
public static java.lang.reflect.Type resolveBound(java.lang.reflect.TypeVariable<?> typeVariable)
Resolves the first bound for thetypeVariable, returningUnknown.classif none can be resolved.
-
populateLambdaArgs
private static void populateLambdaArgs(java.lang.Class<?> functionalInterface, java.lang.Class<?> lambdaType, java.util.Map<java.lang.reflect.TypeVariable<?>,java.lang.reflect.Type> map)Populates themapwith variable/argument pairs for thefunctionalInterface.
-
isDefaultMethod
private static boolean isDefaultMethod(java.lang.reflect.Method m)
-
getMemberRef
private static java.lang.reflect.Member getMemberRef(java.lang.Class<?> type)
-
isAutoBoxingMethod
private static boolean isAutoBoxingMethod(java.lang.reflect.Method method)
-
wrapPrimitives
private static java.lang.Class<?> wrapPrimitives(java.lang.Class<?> clazz)
-
getConstantPoolSize
private static int getConstantPoolSize(java.lang.Object constantPool)
-
getConstantPoolMethodAt
private static java.lang.reflect.Member getConstantPoolMethodAt(java.lang.Object constantPool, int i)
-
-