Class TypeView
- java.lang.Object
-
- org.perfectable.introspection.type.TypeView
-
- Direct Known Subclasses:
ArrayTypeView
,ClassView
,ParameterizedTypeView
,TypeVariableView
,WildcardTypeView
public abstract class TypeView extends Object
Simplified and more useful handle of javaType
.This type is a facade over
Type
and its all five descendants, that offers unified interface to them.It allows easy tests for it:
- Subtyping and supertyping
- Getting actual erasure
In addition, this type allows to "resolve" one type in context of another. Resolving means using variable replacements of context type in with current type. See
resolve(java.lang.reflect.Type)
.Instances of this type are immutable, as long as provided implementations of
Type
and its descendant are. Plain java constructs of those are immutable.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
TypeView.PartialVisitor<T>
Implementation ofTypeView.Visitor
that has default method.static interface
TypeView.Visitor<T>
Visitor pattern interface.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract ArrayTypeView
asArray()
Try to cast/convert wrapped type toGenericArrayType
.abstract ClassView<?>
asClass()
Try to cast or convert wrapped type toClass
.abstract ParameterizedTypeView
asParameterized()
Try to cast or convert wrapped type toParameterizedType
.abstract TypeVariableView<?>
asVariable()
Try to cast wrapped type toTypeVariable
.abstract WildcardTypeView
asWildcard()
Try to cast wrapped type toWildcardType
.abstract Class<?>
erasure()
Finds exact class that would be erasure of wrapped type.boolean
isInstance(Object element)
Tests if provided value is instance of wrapped type.boolean
isProperSubtypeOf(Type other)
Tests if type wrapped in this view is subtype of the provided one, but they are not the same type.boolean
isProperSubtypeOf(TypeView other)
Tests if type wrapped in this view is subtype of the provided one, but they are not the same type.boolean
isProperSupertypeOf(Type other)
Tests if type wrapped in this view is supertype of the provided one, but they are not the same type.boolean
isProperSupertypeOf(TypeView other)
Tests if type wrapped in this view is supertype of the provided one, but they are not the same type.boolean
isSubTypeOf(Type other)
Tests if type wrapped in this view is subtype of the provided one.abstract boolean
isSubTypeOf(TypeView other)
Tests if type wrapped in this view is subtype of the provided one.boolean
isSuperTypeOf(Type other)
Tests if type wrapped in this view is supertype of the provided one.boolean
isSuperTypeOf(TypeView other)
Tests if type wrapped in this view is supertype of the provided one.static <X> ClassView<X>
of(Class<X> clazz)
Creates view over provided type.static ArrayTypeView
of(GenericArrayType genericArray)
Creates view over provided type.static ParameterizedTypeView
of(ParameterizedType parameterized)
Creates view over provided type.static TypeView
of(Type type)
Creates view over provided type.static <D extends GenericDeclaration>
TypeVariableView<D>of(TypeVariable<D> variable)
Creates view over provided type.static WildcardTypeView
of(WildcardType wildcard)
Creates view over provided type.static TypeView
ofParameterOf(Method method, int number)
Returns view of n-th formal parameter declared in method.static TypeView
ofTypeOf(Field field)
Returns view of corrected type for declared field.static TypeVariableView<Method>
ofTypeParameterOf(Method method, int number)
Returns view of n-th type parameter declared in method.TypeView
resolve(Type other)
Create view that has variable substitutions copied from provided.TypeView
resolve(TypeView other)
Create view that has variable substitutions copied from provided.abstract Type
unwrap()
Extracts native type from this view.abstract <T> T
visit(TypeView.Visitor<T> visitor)
Visitor patter method dispatching method.
-
-
-
Method Detail
-
of
public static TypeView of(Type type)
Creates view over provided type.- Parameters:
type
- construct to wrap- Returns:
- view wrapping specified type
-
of
public static ParameterizedTypeView of(ParameterizedType parameterized)
Creates view over provided type.This is a overload when argument is known to be
ParameterizedType
, to returnParameterizedTypeView
- Parameters:
parameterized
- construct to wrap- Returns:
- view wrapping specified type
-
of
public static <X> ClassView<X> of(Class<X> clazz)
Creates view over provided type.This is a overload when argument is known to be
Class
, to returnClassView
- Type Parameters:
X
- actual type represented by this class- Parameters:
clazz
- construct to wrap- Returns:
- view wrapping specified type
-
of
public static <D extends GenericDeclaration> TypeVariableView<D> of(TypeVariable<D> variable)
Creates view over provided type.This is a overload when argument is known to be
TypeVariable
, to returnTypeVariableView
- Type Parameters:
D
- element type that is declaring this variable- Parameters:
variable
- construct to wrap- Returns:
- view wrapping specified type
-
of
public static WildcardTypeView of(WildcardType wildcard)
Creates view over provided type.This is a overload when argument is known to be
WildcardType
, to returnWildcardTypeView
- Parameters:
wildcard
- construct to wrap- Returns:
- view wrapping specified type
-
of
public static ArrayTypeView of(GenericArrayType genericArray)
Creates view over provided type.This is a overload when argument is known to be
GenericArrayType
, to returnArrayTypeView
- Parameters:
genericArray
- construct to wrap- Returns:
- view wrapping specified type
-
ofTypeOf
public static TypeView ofTypeOf(Field field)
Returns view of corrected type for declared field.- Parameters:
field
- to extract type from- Returns:
- view of type of declared field
-
ofTypeParameterOf
public static TypeVariableView<Method> ofTypeParameterOf(Method method, int number) throws IllegalArgumentException
Returns view of n-th type parameter declared in method.This extracts exactly type parameters that are declared with method, not type of method formal parameter.
In following example,
ofTypeParameterOf(<m>, 0)
returnsE
, notString
.public <E> void m(String i, E j)
For extraction of type of formal parameter, see
ofParameterOf(java.lang.reflect.Method, int)
.- Parameters:
method
- to extract type fromnumber
- ordinal number for searched type parameter, counted from0
- Returns:
- view of type parameter
- Throws:
IllegalArgumentException
- when type parameter numbernumber
is not within method type parameter range- See Also:
ofParameterOf(java.lang.reflect.Method, int)
-
ofParameterOf
public static TypeView ofParameterOf(Method method, int number)
Returns view of n-th formal parameter declared in method.This extracts exactly formal parameters of method, not type of type parameter declared by method.
In following example,
ofTypeParameterOf(<m>, 0)
returnsString
, notE
.public <E> void m(String i, E j)
For extraction of type parameter, see
ofTypeParameterOf(java.lang.reflect.Method, int)
.- Parameters:
method
- to extract type fromnumber
- ordinal number for searched formal parameter, counted from0
- Returns:
- view of type of formal parameter
- Throws:
IllegalArgumentException
- when type parameter numbernumber
is not within method formal parameter range- See Also:
ofTypeParameterOf(java.lang.reflect.Method, int)
-
unwrap
public abstract Type unwrap()
Extracts native type from this view.This is inverse operation from
of(Type)
- Returns:
- type that this view was for
-
erasure
public abstract Class<?> erasure()
Finds exact class that would be erasure of wrapped type.This method is implemented according to JSL section 4.6 with following extensions:
- Erasure of wildcard type is erasure of its leftmost upper bound,
or
Object
if there isn't one
These extensions are needed, because these types are cannot be used in declaration, but can be obtained by reflections.
- Returns:
- erasure of wrapped type
- Erasure of wildcard type is erasure of its leftmost upper bound,
or
-
isSubTypeOf
public abstract boolean isSubTypeOf(TypeView other)
Tests if type wrapped in this view is subtype of the provided one.This method tries to adhere to the spirit of subtyping: it answers the question: Having reference of type T, can value of type S be always assigned to it?
Subtyping is precisely defined for types that can be declared in source, but there are more types that can be constructed or extracted via reflections. This method follows JLS section 4.10 for every aspect it declares, but also defines sensible rule for subtyping wildcards: wildcard is a supertype of its lower bounds, i.e.
? super CharStream
is supertype of CharStream and- Parameters:
other
- type to test subtype relation against- Returns:
- true if this type is subtype of provided argument
-
isSubTypeOf
public boolean isSubTypeOf(Type other)
Tests if type wrapped in this view is subtype of the provided one.See
isSubTypeOf(org.perfectable.introspection.type.TypeView)
for more.- Parameters:
other
- type to test subtype relation against- Returns:
- true if this type is subtype of provided argument
-
isProperSubtypeOf
public boolean isProperSubtypeOf(TypeView other)
Tests if type wrapped in this view is subtype of the provided one, but they are not the same type.See
isSubTypeOf(org.perfectable.introspection.type.TypeView)
for more about testing how subtyping is calculated.- Parameters:
other
- type to test subtype relation against- Returns:
- true if this type is subtype of provided argument
-
isProperSubtypeOf
public boolean isProperSubtypeOf(Type other)
Tests if type wrapped in this view is subtype of the provided one, but they are not the same type.See
isSubTypeOf(org.perfectable.introspection.type.TypeView)
for more about testing how subtyping is calculated.- Parameters:
other
- type to test subtype relation against- Returns:
- true if this type is subtype of provided argument
-
isSuperTypeOf
public boolean isSuperTypeOf(TypeView other)
Tests if type wrapped in this view is supertype of the provided one.Type T is supertype of S iff S is subtype of T.
- Parameters:
other
- type to test supertype relation against- Returns:
- true if this type is supertype of provided argument
-
isSuperTypeOf
public boolean isSuperTypeOf(Type other)
Tests if type wrapped in this view is supertype of the provided one.Type T is supertype of S iff S is subtype of T.
- Parameters:
other
- type to test supertype relation against- Returns:
- true if this type is supertype of provided argument
-
isProperSupertypeOf
public boolean isProperSupertypeOf(TypeView other)
Tests if type wrapped in this view is supertype of the provided one, but they are not the same type.Type T is supertype of S iff S is subtype of T.
- Parameters:
other
- type to test supertype relation against- Returns:
- true if this type is supertype of provided argument
-
isProperSupertypeOf
public boolean isProperSupertypeOf(Type other)
Tests if type wrapped in this view is supertype of the provided one, but they are not the same type.Type T is supertype of S iff S is subtype of T.
- Parameters:
other
- type to test supertype relation against- Returns:
- true if this type is supertype of provided argument
-
isInstance
public boolean isInstance(@Nullable Object element)
Tests if provided value is instance of wrapped type.Because of type erasure, this method only tests if erasure of provided element type is subtype of this type. This might not always be true! For example, for method
boolean m(List<? extends Number> t)
extracted parameter type isList<? extends Number>
butt
has runtime typeList
. If we have view of typeList<? extends Serializable>
, thenisInstance(t)
should return true, when in fact it will return false, as runtime class is treated as parameterized class with no substitutions.As in plain java,
null
is subtype of only of null type, which cannot be obtained as a reference, so this will always return false for it.See
isSubTypeOf(org.perfectable.introspection.type.TypeView)
for how subtyping is calculated.- Parameters:
element
- type to test supertype relation against- Returns:
- true if this type is supertype of provided argument
-
asParameterized
public abstract ParameterizedTypeView asParameterized() throws IllegalStateException
Try to cast or convert wrapped type toParameterizedType
.This method is useful if you know that underlying type is
ParameterizedType
, then this is just a casting.This can also be done for regular classes,
ClassView
, as non-generic class can be treated as generic class with zero type parameters. It also works for class-represented arrays that are currently converted to parameterized types.- Returns:
- this view casted/converted to view for parameterized type
- Throws:
IllegalStateException
- when this view cannot be converted to ParameterizedView.
-
asClass
public abstract ClassView<?> asClass() throws IllegalStateException
Try to cast or convert wrapped type toClass
.This method is useful if you know that underlying type is
Class
, then this is just a casting.This can also be done for parameterized types with no actual substitutions and array classes represented by
ArrayTypeView
- Returns:
- this view casted/converted to view for class
- Throws:
IllegalStateException
- when this view cannot be converted to Class.
-
asVariable
public abstract TypeVariableView<?> asVariable() throws IllegalStateException
Try to cast wrapped type toTypeVariable
.This method is useful if you know that underlying type is
Class
, then this is just a casting.For any other type, this throws
IllegalStateException
, because nothing else can be converted to type variable.- Returns:
- this view casted to view for type variable
- Throws:
IllegalStateException
- when this view is not a view of TypeVariable.
-
asWildcard
public abstract WildcardTypeView asWildcard() throws IllegalStateException
Try to cast wrapped type toWildcardType
.This method is useful if you know that underlying type is
WildcardType
, then this is just a casting.For any other type, this throws
IllegalStateException
, because nothing else can be converted to type wildcard.- Returns:
- this view casted to view for wildcard type
- Throws:
IllegalStateException
- when this view is not a view of WildcardType.
-
asArray
public abstract ArrayTypeView asArray() throws IllegalStateException
Try to cast/convert wrapped type toGenericArrayType
.This method is useful if you know that underlying type is
GenericArrayType
, then this is just a casting.This can also be done for parameterized types with no actual substitutions that represetn array class, and class view that has array class.
- Returns:
- this view casted/converted to view for array
- Throws:
IllegalStateException
- when this view cannot be converted to view of GenericArrayType.
-
resolve
public TypeView resolve(Type other)
Create view that has variable substitutions copied from provided.See documentation on
resolve(TypeView)
for details.- Parameters:
other
- type to copy substitutions from- Returns:
- TypeView that uses substitutions from provided type
-
resolve
public TypeView resolve(TypeView other)
Create view that has variable substitutions copied from provided.This method creates type that has any variable substituted by substitutions used in
other
.Substitutions are found recursively. They can be only directly found in parameterized types, as arguments, but these parameterized types can be found in components of some containing type. For example, wildcard might use parameterized type as a bound, and this parameterized type might have substitution for specific variable.
This method can be used to find what the signature of field or method looks like in some specific type. For example: lets say that there's a generic class
class Example<T>
that declares fieldprotected List<T> elements
. It's descendant class, declaredclass ExtendedExample extends Example<String>
inherits fieldelements
. In this case no conventional method will extract actual field type,List<String>
:- Field found by
Class.getDeclaredField(java.lang.String)
called onExampleExtension
will return null, as this field is not declared there. - Field found by
Class.getDeclaredField(java.lang.String)
called onExample
(orClass.getField(java.lang.String)
on child class, if the field would be public) will return field from parent class, executingField.getGenericType()
on it will returnList<T>
TypeView.ofTypeOf(Example.class.getDeclaredField("elements")).resolve(ExampleExtension.class)
will wrapList<String>
, because variable substitutionT
->String
is used.- Parameters:
other
- type to copy substitutions from- Returns:
- TypeView that uses substitutions from provided type
- Field found by
-
visit
public abstract <T> T visit(TypeView.Visitor<T> visitor)
Visitor patter method dispatching method.This method calls specific method on provided
visitor
, depending on actual implementation of this type.It will return whatever the method returns.
- Type Parameters:
T
- type returned by visitor method- Parameters:
visitor
- method target- Returns:
- same result as visitors method.
-
-