public class GenericsContext extends AbstractGenericsContext
AbstractGenericsContext for more information.
Not merged with AbstractGenericsContext in order to separate more specific implementation details
from common generic utility methods.
AbstractGenericsContext,
inlyingType(java.lang.reflect.Type)| Modifier and Type | Class and Description |
|---|---|
class |
GenericsContext.RootContextAwareTypeWriter
Hierarchy writer with root context info (if available).
|
| Modifier and Type | Field and Description |
|---|---|
protected java.util.Map<java.lang.String,java.lang.reflect.Type> |
allTypeGenerics |
static java.lang.String |
CURRENT_POSITION_MARKER
Current hierarchy position marker (for toString).
|
protected java.util.Map<java.lang.String,java.lang.reflect.Type> |
ownerGenerics |
protected java.lang.Class<?> |
ownerType |
currentType, genericsInfo, typeGenerics| Constructor and Description |
|---|
GenericsContext(GenericsInfo genericsInfo,
java.lang.Class<?> type) |
GenericsContext(GenericsInfo genericsInfo,
java.lang.Class<?> type,
GenericsContext root) |
| Modifier and Type | Method and Description |
|---|---|
GenericsContext |
chooseContext(java.lang.reflect.Type type)
Look for generic variables presence inside type and, if found, try to switch to correct context.
|
ConstructorGenericsContext |
constructor(java.lang.reflect.Constructor constructor)
Navigates current context to specific constructor (type context is switched to constructor declaring class).
|
protected java.util.Map<java.lang.String,java.lang.reflect.Type> |
contextGenerics() |
GenericDeclarationScope |
getGenericsScope()
For example,
CLASS scope could resolve only class level generics, whereas
METHOD could see method context generics. |
java.lang.reflect.GenericDeclaration |
getGenericsSource()
Declaration source could be: class, method or constructor.
|
GenericsContext |
inlyingType(java.lang.reflect.Type type)
Build generics context for type in context of current class.
|
GenericsContext |
inlyingTypeAs(java.lang.reflect.Type type,
java.lang.Class<?> asType)
Build generics context for type extending some generic type in context of current class.
|
boolean |
isInlying()
During reflection analysis it's common to review some internal type like field or method return type.
|
MethodGenericsContext |
method(java.lang.reflect.Method method)
Navigates current context to specific method (type context is switched to method declaring class).
|
java.lang.Class<?> |
ownerClass()
class Owner<T> {
class Inner {
T field;
}
}. |
java.util.Map<java.lang.String,java.lang.reflect.Type> |
ownerGenericsMap()
Inner class may use outer generics like this:
class Owner<T> {
class Inner {
T field;
}
}. |
GenericsContext |
rootContext() |
protected GenericsContext |
switchContext(java.lang.Class target,
java.lang.String msgPrefix)
Used to switch to appropriate context or fail if type is not found in hierarchy.
|
java.lang.String |
toString() |
GenericsContext |
type(java.lang.Class<?> type)
Navigates current context to specific type in class hierarchy.
|
currentClass, fieldType, fieldTypeAs, generic, generic, genericAsString, genericAsString, generics, genericsAsString, genericsMap, genericType, genericType, genericTypes, getGenericsInfo, resolveClass, resolveFieldClass, resolveFieldGeneric, resolveFieldGenerics, resolveFieldType, resolveGenericOf, resolveGenericsOf, resolveType, resolveTypeGenerics, toStringCurrentClass, toStringCurrentClassDeclaration, toStringType, visibleGenericsMappublic static final java.lang.String CURRENT_POSITION_MARKER
protected java.lang.Class<?> ownerType
protected java.util.Map<java.lang.String,java.lang.reflect.Type> ownerGenerics
protected java.util.Map<java.lang.String,java.lang.reflect.Type> allTypeGenerics
public GenericsContext(GenericsInfo genericsInfo, java.lang.Class<?> type)
public GenericsContext(GenericsInfo genericsInfo, java.lang.Class<?> type, GenericsContext root)
public java.lang.Class<?> ownerClass()
class Owner<T> {
class Inner {
T field;
}
}.
For Inner class owner is Owner. For Owner class owner is null.
Note: interface class is always static (can't be inner, even if declared as inner).
ownerGenericsMap()public GenericsContext rootContext()
inlyingType(Type)public boolean isInlying()
inlyingType(Type)) are called inlying. You can always access root context for inlying using
rootContext().public java.util.Map<java.lang.String,java.lang.reflect.Type> ownerGenericsMap()
class Owner<T> {
class Inner {
T field;
}
}.
NOTE: contains only owner type generics, not hidden by inner class generics. For example:
class Owner<T, K> {
// hides outer generic
class Inner<T> {}
}
Here ownerGenericsMap() == ["K": Object] because owner generic "T" is overridden by inner class
declaration.
In method or constructor contexts, context specific generics may also override owner generics
(e.g. <T> T method();), but still all reachable by class owner generics wll be returned.
This is done for consistency: no matter what context, method will return the same map. The only exception
is AbstractGenericsContext.visibleGenericsMap() which return only actually visible generics from current context
(class, method or constructor).
ownerClass()public java.lang.String toString()
toString in class java.lang.Objectpublic GenericDeclarationScope getGenericsScope()
AbstractGenericsContextCLASS scope could resolve only class level generics, whereas
METHOD could see method context generics. May be used for current context differentiation
(instead of instanceof).getGenericsScope in class AbstractGenericsContextAbstractGenericsContext.getGenericsSource()public java.lang.reflect.GenericDeclaration getGenericsSource()
AbstractGenericsContextgetGenericsSource in class AbstractGenericsContextAbstractGenericsContext.getGenericsScope()public GenericsContext type(java.lang.Class<?> type)
AbstractGenericsContexttype in class AbstractGenericsContexttype - class to navigate topublic MethodGenericsContext method(java.lang.reflect.Method method)
AbstractGenericsContext<T> void myMethod(T arg);.
Use context to work with method parameters, return type or resolving types inside method.
method in class AbstractGenericsContextmethod - method in current class hierarchy to navigate to (may be method from subclass, relative to
currently selected, in this case context type will be automatically switched)public ConstructorGenericsContext constructor(java.lang.reflect.Constructor constructor)
AbstractGenericsContext<T> MyType(T arg).
Use context to work with constructor arguments.
constructor in class AbstractGenericsContextconstructor - constructor in current class hierarchy to navigate to (may be constructor from subclass,
relative to currently selected, in this case context type is automatically switched)public GenericsContext inlyingType(java.lang.reflect.Type type)
AbstractGenericsContext class A<T> {
private C<T> field;
}
class C extends A<String> {}
To continue analysis of field type: type(A.class).inlyingType(A.class.getField("field")
.getGenericType()) == generics context of C<String>
Use shortcut methods to simplify navigation: AbstractGenericsContext.fieldType(Field),
MethodGenericsContext.returnType(), MethodGenericsContext.parameterType(int) and
ConstructorGenericsContext.parameterType(int).
Check if type containing generics, belonging to different context in current hierarchy and automatically change context to properly resolve generics. Fails when it is impossible to correctly resolve generics (preventing incorrect usage).
If provided type did not contains generic then cached type resolution will be used (the same as
GenericsResolver.resolve(Target.class) and if generics present then type will be built on each call.
Returned context holds reference to original (root) context: rootContext().
Ignored types, used for context creation, are counted (will also be ignored for inlying context building).
If provided type is primitive then wrapper will be used instead (for example, Integer instead of
int).
inlyingType in class AbstractGenericsContexttype - type to resolve hierarchy from (it must be generified type, resolved in current class)public GenericsContext inlyingTypeAs(java.lang.reflect.Type type, java.lang.Class<?> asType)
AbstractGenericsContext
Example case: field declaration is SomeInterface<T> field and we need to build inlying context
for actual field value class SomeImpl<K> implements SomeInterface<K>. Type of root generic K will be
tracked from known generic T (on interface), but even if it's not possible to track root generics, hierarchy
starting from known type (interface in this case) will use correct generic value. This way, all known
generics information is used.
Other than different target type, method is the same as AbstractGenericsContext.inlyingType(Type). By analogy, shortcuts
are provided for simpler navigation: AbstractGenericsContext.fieldTypeAs(Field, Class),
MethodGenericsContext.returnTypeAs(Class), MethodGenericsContext.parameterTypeAs(int, Class)
and ConstructorGenericsContext.parameterTypeAs(int, Class).
If provided type is primitive then wrapper will be used instead (for example, Integer instead of
int).
inlyingTypeAs in class AbstractGenericsContexttype - type to resolve actual generics from (it must be generified type, resolved in current class)asType - required target type to build generics context for (must include declared type as base class)AbstractGenericsContext.inlyingType(Type)public GenericsContext chooseContext(java.lang.reflect.Type type)
AbstractGenericsContext
Note that WrongGenericsContextException used instead of IllegalArgumentException, as in
other cases, because it is more specific error: type may come from anywhere and it may be not so easy to
track it's correct usage.
chooseContext in class AbstractGenericsContexttype - type, possibly containing generic variablesprotected GenericsContext switchContext(java.lang.Class target, java.lang.String msgPrefix)
AbstractGenericsContextNote that this method may seem useless as correct context is always selected based on type generics, but method is required to show more specific error (better indicating context).
switchContext in class AbstractGenericsContexttarget - target typemsgPrefix - error message prefix, identifying placeAbstractGenericsContext.chooseContext(Type)protected java.util.Map<java.lang.String,java.lang.reflect.Type> contextGenerics()
contextGenerics in class AbstractGenericsContext