public final class GenericsResolutionUtils
extends java.lang.Object
| Modifier and Type | Method and Description |
|---|---|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
fillOuterGenerics(java.lang.reflect.Type type,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> generics,
java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> knownGenerics)
Inner class could reference outer class generics and so this generics must be included into class context.
|
static java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> |
resolve(java.lang.Class<?> type,
java.lang.Class<?>... ignoreClasses)
Analyze class hierarchy and resolve actual generic values for all composing types.
|
static java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> |
resolve(java.lang.Class<?> type,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> rootGenerics,
java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> knownGenerics,
java.util.List<java.lang.Class<?>> ignoreClasses)
Analyze class hierarchy and resolve actual generic values for all composing types.
|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
resolveDirectRawGenerics(java.lang.Class<?> type)
Resolve type generics by declaration (as upper bound).
|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
resolveDirectRawGenerics(java.lang.reflect.Constructor constructor,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
Resolve constructor generics by declaration (as upper bound).
|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
resolveDirectRawGenerics(java.lang.reflect.Method method,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
Resolve method generics by declaration (as upper bound).
|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
resolveGenerics(java.lang.reflect.Type type,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
Resolve declared generics for type (actually declared generics in context of some type).
|
static java.lang.reflect.Type |
resolveRawGeneric(java.lang.reflect.TypeVariable variable,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> generics)
Extracts declared upper bound from generic declaration.
|
static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> |
resolveRawGenerics(java.lang.Class<?> type)
Resolve type generics by declaration (as upper bound).
|
public static java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> resolve(java.lang.Class<?> type,
java.lang.Class<?>... ignoreClasses)
type - type to resolve generics forignoreClasses - classes to ignore (if required)for more custom resolutionpublic static java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> resolve(java.lang.Class<?> type,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> rootGenerics,
java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> knownGenerics,
java.util.List<java.lang.Class<?>> ignoreClasses)
If generics are known for some middle type, then they would be used "as is" instead of generics tracked from root. Also, known generics will be used for lower hierarchy resolution.
type - class to analyzerootGenerics - resolved root type generics (including owner type generics); must not be null!knownGenerics - type generics known before analysis (some middle class generics are known) and
could contain possible outer generics (types for sure not included in resolving type
hierarchy); must not be null, but could be empty mapignoreClasses - classes to ignore during analysispublic static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> resolveGenerics(java.lang.reflect.Type type,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
If type is not ParameterizedType and so does not contains actual generics info, resolve
generics from type declaration (resolveRawGenerics(Class)),
type - type to resolve generics forgenerics - generics of context classpublic static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> resolveRawGenerics(java.lang.Class<?> type)
Some<T>).
If class is inner class, resolve outer class generics (which may be used in class)
type - class to analyze generics forto resolve without outer typepublic static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> resolveDirectRawGenerics(java.lang.Class<?> type)
Some<T>).type - class to analyze generics forto include outer type genericspublic static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> resolveDirectRawGenerics(java.lang.reflect.Method method,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
public <T extends Serializable> do(T param)
contains generic T which must be resolved as Serializable.method - method to analyze generics forgenerics - context class generics (which could be used in method generics declarations)public static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> resolveDirectRawGenerics(java.lang.reflect.Constructor constructor,
java.util.Map<java.lang.String,java.lang.reflect.Type> generics)
public <T extends Serializable> MyType(T param)
contains generic T which must be resolved as Serializable.constructor - constructor to analyze generics forgenerics - context class generics (which could be used in constructor generics declarations)public static java.lang.reflect.Type resolveRawGeneric(java.lang.reflect.TypeVariable variable,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> generics)
Base<T> will be resolved
as Object (default bound). Base<T extends A & B> resolved as "impossible" wildcard
? extends A & B in order to preserve all known information.
Map of already resolved generics is required because declaration may rely on them. For example,
Base<T extends Serializable, K extends T> could be solved as T = Serializable, K = Serializable.
variable - generic declaration to analyzegenerics - already resolved generics (on the left of current)public static java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> fillOuterGenerics(java.lang.reflect.Type type,
java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type> generics,
java.util.Map<java.lang.Class<?>,java.util.LinkedHashMap<java.lang.String,java.lang.reflect.Type>> knownGenerics)
Outer generics could be included into declaration like Outer<String>.Inner field. In this case
incoming type should be ParameterizedType with generified owner.
When provided type is simply a class (or anything resolvable to class), then outer class generics are resolved as upper bound (by declaration). Class may declare the same generic name and, in this case, outer generic will be ignored (as not visible).
During inlying context resolution, if outer generic is not declared in type we can try to guess it: we know outer context, and, if outer class is in outer context hierarchy, we could assume that it's actual parent class and so we could use more specific generics. This will be true for most sane cases (often inner class is used inside owner), but other cases are still possible (anyway, the chance that inner class will appear in two different hierarchies of outer class is quite small).
It is very important to use returned map instead of passed in map because, incoming empty map is always replaced to avoid modifications of shared empty maps.
type - context typegenerics - resolved type genericsknownGenerics - map of known middle generics and possibly known outer context (outer context may contain
outer class generics declarations). May be null.