public final class Types extends Object
Type
,
TypeRef
,
AnnotatedTypes
Modifier and Type | Method and Description |
---|---|
static Class<?> |
box(Class<?> clazz)
Boxes the given class if it is a primitive type.
|
static Type |
box(Type type)
Boxes the given type if it is a primitive type.
|
static boolean |
equals(Type a,
Type b)
Returns true if both of the given types refer to the same type or are equivalent.
|
static WildcardType |
extendsAnyWildcard()
|
static Type[] |
getActualTypeArguments(Type type)
Returns the actual type arguments if the given type is a parameterized type.
|
static Set<Type> |
getAllSupertypes(Type type)
Returns the set of all supertypes for the given type.
|
static <A extends Annotation> |
getAnnotation(Type type,
Class<A> annotationType)
Finds the given annotation on the given type.
|
static Annotation[] |
getAnnotations(Type type)
Finds all annotations on the given type.
|
static <T> Class<T[]> |
getArrayType(Class<T> componentType)
Gets the class token that represents an array of the given component type.
|
static Type |
getArrayType(Type componentType)
Returns an array type with the given component type.
|
static Type |
getComponentType(Type type)
Returns the component type of the given array type.
|
static Annotation[] |
getDeclaredAnnotations(Type type)
Finds all annotations declared on the given type.
|
static Type[] |
getDirectSupertypes(Type type)
Returns the set of direct supertypes for the given type.
|
static Class<?> |
getErasure(Type type)
Determines the erasure for the given type.
|
static Type[] |
getGenericInterfaces(Type type)
Returns the generic interfaces implemented by the given type.
|
static Type |
getGenericSuperclass(Type type)
Returns the generic superclass of the given type.
|
static Class<?>[] |
getInterfaces(Type type)
Returns the interfaces implemented by the given type.
|
static Type[] |
getLeastUpperBounds(Iterable<Type> types)
Computes least upper bounds for the given types.
|
static Type[] |
getLeastUpperBounds(Type... types)
Computes least upper bounds for the given array of types.
|
static Type |
getOwnerType(Type type)
Returns the owner of the given type.
|
static Class<?> |
getSuperclass(Type type)
Returns the superclass of the given type.
|
static TypeVariable<Class<?>>[] |
getTypeParameters(Type type)
Returns the type parameters for the given type or an empty array if it has none.
|
static <D extends GenericDeclaration> |
getTypeVariable(String name,
D declaration)
Gets the
TypeVariable from the given declaration site (class, method, or constructor)
for the given name. |
static <D extends GenericDeclaration> |
getTypeVariablesAsMap(D declaration)
Retrieves the type variables of the given declaration site as a map of type parameter names to
TypeVariable s. |
static Object |
getZeroValue(Type type)
Determines the zero, of default, value for a given type.
|
static int |
hashCode(Type type)
Computes a hash code for the given generic type.
|
static boolean |
isAnnotation(Type type)
Determines if the given type is an annotation type.
|
static boolean |
isArray(Type type)
Returns true if the given type represents an array type.
|
static boolean |
isAssignable(Type from,
Type to)
Determines if one type is assignable to another.
|
static boolean |
isAssignableStrict(Type from,
Type to)
Determines if one type is assignable to another, with restrictions.
|
static boolean |
isEnum(Type type)
Determines if the given type is an enum type.
|
static boolean |
isFunctionalInterface(Type type)
Returns true if the given type represents a functional interface.
|
static boolean |
isGeneric(Class<?> clazz)
Determines if the given class is generic.
|
static boolean |
isGeneric(Type type)
Determines if the given type is a generic type.
|
static boolean |
isInterface(Type type)
Determines if the given type is an interface type.
|
static boolean |
isPrimitive(Type type)
Determines if the given type is one of the eight primitive types or
void . |
static boolean |
isSameType(Type a,
Type b)
Determines whether two given types represent the same type.
|
static boolean |
isSubtype(Type possibleSubtype,
Type aType)
Determines if one type is a proper subtype of another.
|
static boolean |
isSubtypeStrict(Type possibleSubtype,
Type aType)
Determines if one type is a proper subtype of another, with restrictions.
|
static WildcardType |
newExtendsWildcardType(Type bound)
Creates a new
WildcardType with an upper bound, i.e. ? extends T . |
static GenericArrayType |
newGenericArrayType(Type componentType)
Creates a new
GenericArrayType object with the given component type. |
static ParameterizedType |
newParameterizedType(Class<?> rawType,
List<Type> typeArguments)
Creates a new
ParameterizedType for a generic top-level or static type. |
static ParameterizedType |
newParameterizedType(Class<?> rawType,
Type... typeArguments)
Creates a new
ParameterizedType for a generic top-level or static type. |
static ParameterizedType |
newParameterizedType(ParameterizedType ownerType,
Class<?> rawType,
List<Type> typeArguments)
Creates a new
ParameterizedType for a generic enclosed type. |
static ParameterizedType |
newParameterizedType(ParameterizedType ownerType,
Class<?> rawType,
Type... typeArguments)
Creates a new
ParameterizedType for a generic enclosed type. |
static WildcardType |
newSuperWildcardType(Type bound)
Creates a new
WildcardType with a lower bound, i.e. ? super T . |
static Type |
replaceTypeVariable(Type type,
TypeVariable<?> typeVariable,
Type typeValue)
Computes a new version of the given type by replacing all occurrences of a given type variable
with a given value for that variable.
|
static Type |
replaceTypeVariables(Type type,
Map<TypeVariable<?>,Type> typeVariables)
Computes a new version of the given type by replacing all occurrences of mapped type variables
with the given mapped values.
|
static Type |
resolveSupertype(Type type,
Class<?> superClass)
For the given generic type, computes the generic supertype corresponding to the given raw
class token.
|
static Type |
resolveType(Type context,
Type typeToResolve)
Resolves the given type in the context of another type.
|
static Type |
resolveTypeVariable(Type context,
TypeVariable<?> variable)
Resolves the given type variable in the context of the given type.
|
static String |
toString(Type type)
Constructs a string representation of the given type.
|
static Class<?> |
unbox(Class<?> clazz)
Unboxes the given class if it is a wrapper for a primitive type.
|
static Type |
unbox(Type type)
Unboxes the given type if it is a primitive type.
|
public static Class<?> getErasure(Type type)
These are the same rules as defined in Type Erasure (JLS 4.6).
type
- a generic typepublic static Object getZeroValue(Type type)
null
. But for methods that return primitives, this will be the primitive type's
zero value (e.g. zero or false).type
- the typepublic static boolean isArray(Type type)
type
- a generic typepublic static Type getComponentType(Type type)
null
is returned.type
- a generic typenull
if the given type does not
represent an array typepublic static boolean isInterface(Type type)
type
- a generic typepublic static boolean isEnum(Type type)
type
- a generic typepublic static boolean isAnnotation(Type type)
type
- a generic typepublic static boolean isPrimitive(Type type)
void
.type
- a generic typepublic static Class<?> box(Class<?> clazz)
byte
then this returns the wrapper type Byte
. If the given class is not a
primitive type then it is returned, unchanged.clazz
- a classpublic static Type box(Type type)
box(Class)
except
that it accepts any generic type. If the given type is not a raw class then it is returned
unchangedtype
- a generic typepublic static Class<?> unbox(Class<?> clazz)
Byte
then this returns the primitive type byte
. If the given class is
not a wrapper type then it is returned, unchanged.clazz
- a classpublic static Type unbox(Type type)
unbox(Class)
except that it accepts any generic type. If the given type is not a raw class then it is
returned unchangedtype
- a generic typepublic static Class<?> getSuperclass(Type type)
void
, if it is Object
, or if it is an interface then null
is
returned. If the given type is an array type then Object
is the returned superclass.
If the given type is a wildcard or type variable (and is not an interface) then its first upper bound is its superclass.
type
- a generic typeClass.getSuperclass()
,
getGenericSuperclass(Type)
public static Class<?>[] getInterfaces(Type type)
Serializable
and Cloneable
is returned. If the given type is a
class that does not directly implement any interfaces (including primitive types) then an
empty array is returned.
If the given type is a wildcard or type variable, then this returns an array containing any upper bounds that are interfaces.
type
- a generic typeClass.getInterfaces()
,
getGenericInterfaces(Type)
public static Type getGenericSuperclass(Type type)
void
, if it is Object
, or if it is an interface then
null
is returned. If the given type is an array type then Object
is the
returned superclass.
If the given type is a wildcard or type variable (and is not an interface) then its first upper bound is its superclass.
This differs from getSuperclass(Type)
in that it can return a non-raw type. For
example if a wildcard's bound is a parameterized type or if a class extends a parameterized
type (e.g. class MyClass extends ArrayList<String>
) then a parameterized type is
returned.
This can differ from the classes that may be present in getDirectSupertypes(Type)
.
This method is similar to Class.getGenericSuperclass()
in how array and primitive
types are handled: all array types return Object
, and all primitive types return
null
. Whereas getDirectSupertypes(Type)
uses the rules defined in
Subtyping among Primitive Types
(JLS
4.10.1) and Subtyping among Array Types
(JLS
4.10.3)
type
- a generic typeClass.getGenericSuperclass()
public static Type[] getGenericInterfaces(Type type)
Serializable
and Cloneable
is returned. If the given
type is a class that does not directly implement any interfaces (including primitive types)
then an empty array is returned.
If the given type is a wildcard or type variable, then this returns an array containing any upper bounds that are interfaces.
This differs from getInterfaces(Type)
in that it can return a non-raw type. For
example if a wildcard type has an interface bound that is a parameterized type or if a class
implements a parameterized type (e.g. class MyClass implements List<String>
) then a
parameterized type is returned.
This can differ from the interfaces present in getDirectSupertypes(Type)
. This
method is similar to Class.getGenericInterfaces()
in how array types are handled: all
array types return Cloneable
and Serializable
. Whereas
getDirectSupertypes(Type)
returns no interfaces unless Object[]
or a
primitive array type is given.
type
- a generic typeClass.getGenericInterfaces()
public static Type getOwnerType(Type type)
null
. Array types, wildcard types, and
type variables do not have owners, though their component types / bounds might. So this method
return null
if given such a type.
For non-static inner classes, the owner could be a parameterized type. In other cases, the
owner type will be a raw type (e.g. a Class
token)
type
- the generic typenull
if it has no ownerClass.getDeclaringClass()
,
ParameterizedType.getOwnerType()
public static <A extends Annotation> A getAnnotation(Type type, Class<A> annotationType)
null
is returned.
If the given type is a wildcard type or a type variable then the annotation must be
inherited from the type's superclass (if it has one). Otherwise, null
will be
returned.
type
- the generic typeannotationType
- the annotation typenull
if no such annotation existsClass.getAnnotation(Class)
public static Annotation[] getAnnotations(Type type)
If the given type is a wildcard type or a type variable then the annotations must be inherited from the type's superclass (if it has one). Otherwise, an empty array will be returned.
type
- the generic typeClass.getAnnotations()
public static Annotation[] getDeclaredAnnotations(Type type)
If the given type is an array type, a wildcard type, or a type variable then an empty array is returned.
type
- the generic typeClass.getDeclaredAnnotations()
public static boolean equals(Type a, Type b)
a
- a typeb
- another typepublic static final int hashCode(Type type)
equals(Object)
or hashCode()
definitions. So this method computes a stable
hash, regardless of the underlying type implementation.type
- a generic typepublic static String toString(Type type)
toString()
definition, this method can be used to construct a suitable
string representation, regardless of the underlying type implementation.type
- a generic typepublic static boolean isAssignable(Type from, Type to)
There is also a stricter version, that behaves more like
Class.isAssignableFrom(Class)
, but supporting generic types instead of only raw types.
from
- the RHS of assignmentto
- the LHS of assignmentpublic static boolean isAssignableStrict(Type from, Type to)
This is effectively the same as Class.isAssignableFrom(Class)
but supports generic
types instead of only raw types. To that end, it returns true if from
can be assigned
to to
using either Identity Conversion
(JLS
5.1.1) or Widening Reference Conversion
(JLS
5.1.4).
Of particular note, this method does not check for assignability via Widening Primitive Conversion (JLS 5.1.3), Boxing and Unboxing Conversions (JLS 5.1.7 and 5.1.8), or Unchecked Conversions (JLS 5.1.9). To instead test assignment compatibility using all of these, see the non-strict form.
It follows that, for an assignment that would require an unchecked cast, this function returns false, as in this example:
Type genericType = new TypeRef<List<String>>() {}.asTypes(); Type rawType = List.class; // This returns true, no unchecked cast: Types.isAssignable(rawType, genericType); // This returns false as it requires unchecked cast: Types.isAssignable(genericType, rawType);
Similarly, even though the Java language allows an assignment of an int
value to a
long
variable, this function returns false in this case since it does not perform
widening primitive conversion. This is analogous to the observation that long.class.isAssignableFrom(int.class)
returns false.
from
- the RHS of assignmentto
- the LHS of assignmentpublic static boolean isSubtype(Type possibleSubtype, Type aType)
As this checks if one types is a proper subtype, it will return false if
the two types are the same. To check if a type is the same or a subtype, consider using
Types.isAssignable(possibleSubtype, aType)
.
possibleSubtype
- another typeaType
- a typepublic static boolean isSubtypeStrict(Type possibleSubtype, Type aType)
Class.isAssignableFrom(Class)
:
primitive subtyping rules are ignored. So this will return false if given int
and
short
(even though short
is a subtype of int
per primitive subtyping
rules).
So only the rules defined in Subtyping among Class and Interface Types (JLS 4.10.2) and Subtyping among Array Types (JLS 4.10.3) are used.
As this checks if one types is a proper subtype, it will return false if
the two types are the same. To check if a type is the same or a subtype, consider using
Types.isAssignable(possibleSubtype, aType)
.
possibleSubtype
- another typeaType
- a typepublic static boolean isSameType(Type a, Type b)
It behaves the the same as equals(Type, Type)
with one important caveat: two
wildcard types, even if they have identical bounds (and therefore are equal), are never the
same type. This is because they represent unknown types. Since it cannot be known whether the
types they represent are the same, this method assumes they are not. This behavior mirrors
that of the annotation processing API's method of the same name.
a
- a typeb
- another typepublic static Type[] getDirectSupertypes(Type type)
If invoked for the type Object
, an empty array is returned.
type
- a typepublic static boolean isGeneric(Type type)
Class
tokens for non-parameterizable types (e.g. classes and interfaces with no
type arguments).
If a class has no type arguments but is a non-static member of a class that does have type arguments, that class is parameterizable and thus generic.
type
- a typepublic static boolean isGeneric(Class<?> clazz)
clazz
- a classpublic static Set<Type> getAllSupertypes(Type type)
getDirectSupertypes(Type)
were invoked, and then repeatedly invoked recursively
on the returned supertypes until the entire hierarchy is exhausted (e.g. reach Object
,
which has no supertypes).
This method uses a breadth-first search and returns a set with deterministic iteration order so that types "closer" to the given type appear first when iterating through the set.
If invoked for the type Object
, an empty set is returned.
type
- a typepublic static Type[] getLeastUpperBounds(Type... types)
Types.getLeastUpperBounds(Arrays.asList(types))
.types
- the types whose least upper bounds are computedgetLeastUpperBounds(Iterable)
public static Type[] getLeastUpperBounds(Iterable<Type> types)
The least upper bounds can include up to one class type but multiple interface types. When the bounds include a class type, it will be the first element of the given array (and all subsequent elements interface types).
The JLS indicates that recursive types, which could result in infinite recursion in
computing the least upper bounds, should result in cyclic data structures. Core reflection type
interfaces are generally not expected to be cyclic. So if the computed least upper bound
`lub`
were, for example, to result in Comparable<`lub`>
then a non-cyclic
type, Comparable<?>
would be returned instead.
If a mix of reference and primitive types are given, an empty array is returned since primitive types and reference types have no shared bound.
types
- the types whose least upper bounds are computedpublic static boolean isFunctionalInterface(Type type)
This applies the rules defined in Functional Interfaces (JLS 9.8).
type
- a typepublic static Type resolveTypeVariable(Type context, TypeVariable<?> variable)
Collection.<E>
and the given type is the parameterized type
List<Optional<String>>
, then this will return Optional<String>
.
If the given type variable cannot be resolved then null
is returned. For example,
if the type variable given is Map.<K>
and the given type is List<Number>
, then
the variable cannot be resolved.
context
- the generic type whose context is used to resolve the given variablevariable
- the type variable to resolvenull
if it cannot be resolvedpublic static Type resolveType(Type context, Type typeToResolve)
Map<? extends K, ? extends V>
(where K
and V
are the type variables
of interface Map
) and the given context is the parameterized type
TreeMap<String, List<String>>
then the type returned will be
Map<? extends String, ? extends List<String>>
.
If any type variables present in the given type cannot be resolved, they will be unchanged and continue to refer to type variables in the returned type.
context
- the generic type whose context is used to resolve the given typetypeToResolve
- the generic type to resolvepublic static Type replaceTypeVariable(Type type, TypeVariable<?> typeVariable, Type typeValue)
type
- the type to be resolvedtypeVariable
- the type variabletypeValue
- the value that will replace the type variablepublic static Type replaceTypeVariables(Type type, Map<TypeVariable<?>,Type> typeVariables)
type
- the type to be resolvedtypeVariables
- a map of type variables to valuespublic static Type resolveSupertype(Type type, Class<?> superClass)
null
is returned.
For example, if the given generic type is List<String>
and the given raw class
token is Collection.class
, then this method will resolve type parameters and return a
parameterized type: Collection<String>
.
If the given generic type is a raw class token but represents a type with type parameters,
then raw types are returned. For example, if the generic type is HashMap.class
and
the given raw class token is Map.class
, then this method simply returns the raw type
Map.class
. This is also done if any supertype traversed uses raw types. For example,
if the given type's super-class were defined as class Xyz extends HashMap
, then the
type arguments to HashMap
are lost due to raw type usage and a raw type is returned.
If the given generic type is a raw class token that does not have any type
parameters, then the returned value can still be a generic type. For example, if the given
type is Xyz.class
and that class is defined as class Xyz extends
ArrayList<String>
, then querying for a supertype of List.class
will return a
parameterized type: List<String>
.
If the given generic type is a wildcard type or type variable, its supertypes include all upper bounds (and their supertypes), and the type's hierarchy is traversed as such.
Since array types are co-variant on their component type, this method can resolve other
supertypes to which the given type is assignable. For example, if the given type is
HashMap<String, Number>[]
and the given raw class token queried is Map[].class
then this method will resolve type parameters and return a generic type:
Map<String, Number>[]
.
type
- a generic typesuperClass
- a class token for the supertype to querynull
if the given token is not a supertype of the given
generic typepublic static GenericArrayType newGenericArrayType(Type componentType)
GenericArrayType
object with the given component type. The component
type should not be a Class
since that would be a normal (e.g. not generic) array
type. Also, the component type should not be a wildcard type since the component type of an
array must be knowable.componentType
- the component type of the array.NullPointerException
- if the given argument is null
IllegalArgumentException
- if the given component type is not a
ParameterizedType
, TypeVariable
, or GenericArrayType
public static <T> Class<T[]> getArrayType(Class<T> componentType)
componentType
- the component typepublic static Type getArrayType(Type componentType)
This is a convenience method that will delegate to getArrayType(Class)
or
newGenericArrayType(Type)
, depending on the type of the argument.
componentType
- the component typepublic static TypeVariable<Class<?>>[] getTypeParameters(Type type)
type
- a generic typepublic static Type[] getActualTypeArguments(Type type)
type
- the generic typepublic static ParameterizedType newParameterizedType(Class<?> rawType, Type... typeArguments)
ParameterizedType
for a generic top-level or static type. In this case,
there is no enclosing instance of a generic type, so the resulting parameterized type has no
owner type.rawType
- the class of the parameterized typetypeArguments
- the actual type arguments to the parameterized type (should not be empty)NullPointerException
- if either of the given arguments is null
IllegalArgumentException
- if the raw type is a non-generic type or if no type arguments
are given, if the wrong number of type arguments are given, or if any of the type
arguments is outside the bounds for the corresponding type variablepublic static ParameterizedType newParameterizedType(Class<?> rawType, List<Type> typeArguments)
ParameterizedType
for a generic top-level or static type. In this case,
there is no enclosing instance of a generic type, so the resulting parameterized type has no
owner type.rawType
- the class of the parameterized typetypeArguments
- the actual type arguments to the parameterized type (should not be empty)NullPointerException
- if either of the given arguments is null
IllegalArgumentException
- if the raw type is a non-generic type or if no type arguments
are given, if the wrong number of type arguments are given, or if any of the type
arguments is outside the bounds for the corresponding type variablepublic static ParameterizedType newParameterizedType(ParameterizedType ownerType, Class<?> rawType, Type... typeArguments)
ParameterizedType
for a generic enclosed type. This is necessary for
representing non-static enclosed types whose enclosing type is generic, e.g. GenericType<T, U>.EnclosedType
. The actual type arguments may be empty if the given type is
not generic, and only an enclosing type is generic.ownerType
- the generic enclosing typerawType
- the class of the parameterized typetypeArguments
- the actual type arguments to the parameterized type or an empty list if
the raw type is not a generic typeNullPointerException
- if any of the given arguments is null
IllegalArgumentException
- if the given raw type's owner does not match the given owner
type, if the wrong number of type arguments are given, or if any of the type arguments
is outside the bounds for the corresponding type variablepublic static ParameterizedType newParameterizedType(ParameterizedType ownerType, Class<?> rawType, List<Type> typeArguments)
ParameterizedType
for a generic enclosed type. This is necessary for
representing non-static enclosed types whose enclosing type is generic, e.g. GenericType<T, U>.EnclosedType
. The actual type arguments may be empty if the given raw type
is not generic and only its owner type is generic.ownerType
- the generic enclosing typerawType
- the class of the parameterized typetypeArguments
- the actual type arguments to the parameterized type or an empty list if
the raw type is not a generic typeNullPointerException
- if any of the given arguments is null
or if any of the
elements of typeArguments
is null
IllegalArgumentException
- if the given raw type's owner does not match the given owner
type, if the wrong number of type arguments are given, if any type argument is a
primitive type or void
, or if any of the type arguments is outside the bounds
for the corresponding type variablepublic static <D extends GenericDeclaration> TypeVariable<D> getTypeVariable(String name, D declaration)
TypeVariable
from the given declaration site (class, method, or constructor)
for the given name.name
- the name of the type variabledeclaration
- the site of the generic declaration (a class, method, or constructor)NullPointerException
- if either of the given arguments is null
IllegalArgumentException
- if the given declaration has no type variable with the given
namepublic static <D extends GenericDeclaration> Map<String,TypeVariable<D>> getTypeVariablesAsMap(D declaration)
TypeVariable
s.declaration
- the site of the generic declaration (a class, method, or constructor)public static WildcardType newExtendsWildcardType(Type bound)
WildcardType
with an upper bound, i.e. ? extends T
.bound
- the upper bound for the wildcard typeNullPointerException
- if the given bound is null
IllegalArgumentException
- if the given bound is a primitive type or another wildcard
typepublic static WildcardType extendsAnyWildcard()
WildcardType
with an upper bound of Object
, i.e. ?
.
The returned value is a constant. Multiple calls to this method all return references to that same constant object.
Object
public static WildcardType newSuperWildcardType(Type bound)
WildcardType
with a lower bound, i.e. ? super T
.bound
- the lower bound for the wildcard typeNullPointerException
- if the given bound is null
IllegalArgumentException
- if the given bound is a primitive type or another wildcard
type