Class TypeDescriptor
- java.lang.Object
- org.springframework.core.convert.TypeDescriptor
- All Implemented Interfaces:
Serializable
public class TypeDescriptor extends Object implements Serializable
Contextual descriptor about a type to convert from or to. Capable of representing arrays and generic collection types.- Since:
- 3.0
- Author:
- Keith Donald, Andy Clement, Juergen Hoeller, Phillip Webb, Sam Brannen, Stephane Nicoll
- See Also:
ConversionService.canConvert(TypeDescriptor, TypeDescriptor)
,ConversionService.convert(Object, TypeDescriptor, TypeDescriptor)
, Serialized Form
Constructor Summary
Constructors Modifier Constructor Description TypeDescriptor(Field field)
Create a new type descriptor from aField
.TypeDescriptor(Property property)
Create a new type descriptor from aProperty
.TypeDescriptor(MethodParameter methodParameter)
Create a new type descriptor from aMethodParameter
.protected
TypeDescriptor(ResolvableType resolvableType, Class<?> type, Annotation[] annotations)
Create a new type descriptor from aResolvableType
.
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static TypeDescriptor
array(TypeDescriptor elementTypeDescriptor)
Create a new type descriptor as an array of the specified type.static TypeDescriptor
collection(Class<?> collectionType, TypeDescriptor elementTypeDescriptor)
Create a new type descriptor from aCollection
type.TypeDescriptor
elementTypeDescriptor(Object element)
If this type is aCollection
or an array, creates a element TypeDescriptor from the provided collection or array element.boolean
equals(Object other)
static TypeDescriptor
forObject(Object source)
Create a new type descriptor for an object.<T extends Annotation>
TgetAnnotation(Class<T> annotationType)
Obtain the annotation of the specifiedannotationType
that is on this type descriptor.Annotation[]
getAnnotations()
Return the annotations associated with this type descriptor, if any.TypeDescriptor
getElementTypeDescriptor()
If this type is an array, returns the array's component type.TypeDescriptor
getMapKeyTypeDescriptor()
If this type is aMap
and its key type is parameterized, returns the map's key type.TypeDescriptor
getMapKeyTypeDescriptor(Object mapKey)
If this type is aMap
, creates a mapKeyTypeDescriptor
from the provided map key.TypeDescriptor
getMapValueTypeDescriptor()
If this type is aMap
and its value type is parameterized, returns the map's value type.TypeDescriptor
getMapValueTypeDescriptor(Object mapValue)
If this type is aMap
, creates a mapValueTypeDescriptor
from the provided map value.String
getName()
Return the name of this type: the fully qualified class name.Class<?>
getObjectType()
Variation ofgetType()
that accounts for a primitive type by returning its object wrapper type.ResolvableType
getResolvableType()
Return the underlyingResolvableType
.Object
getSource()
Return the underlying source of the descriptor.Class<?>
getType()
The type of the backing class, method parameter, field, or property described by this TypeDescriptor.boolean
hasAnnotation(Class<? extends Annotation> annotationType)
Determine if this type descriptor has the specified annotation.int
hashCode()
boolean
isArray()
Is this type an array type?boolean
isAssignableTo(TypeDescriptor typeDescriptor)
Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor.boolean
isCollection()
Is this type aCollection
type?boolean
isMap()
Is this type aMap
type?boolean
isPrimitive()
Is this type a primitive type?static TypeDescriptor
map(Class<?> mapType, TypeDescriptor keyTypeDescriptor, TypeDescriptor valueTypeDescriptor)
Create a new type descriptor from aMap
type.TypeDescriptor
narrow(Object value)
Narrows thisTypeDescriptor
by setting its type to the class of the provided value.static TypeDescriptor
nested(Field field, int nestingLevel)
Create a type descriptor for a nested type declared within the field.static TypeDescriptor
nested(Property property, int nestingLevel)
Create a type descriptor for a nested type declared within the property.static TypeDescriptor
nested(MethodParameter methodParameter, int nestingLevel)
Create a type descriptor for a nested type declared within the method parameter.String
toString()
TypeDescriptor
upcast(Class<?> superType)
Cast thisTypeDescriptor
to a superclass or implemented interface preserving annotations and nested type context.static TypeDescriptor
valueOf(Class<?> type)
Create a new type descriptor from the given type.
Constructor Detail
TypeDescriptor
public TypeDescriptor(MethodParameter methodParameter)
Create a new type descriptor from aMethodParameter
.Use this constructor when a source or target conversion point is a constructor parameter, method parameter, or method return value.
- Parameters:
methodParameter
- the method parameter
TypeDescriptor
public TypeDescriptor(Field field)
Create a new type descriptor from aField
.Use this constructor when a source or target conversion point is a field.
- Parameters:
field
- the field
TypeDescriptor
public TypeDescriptor(Property property)
Create a new type descriptor from aProperty
.Use this constructor when a source or target conversion point is a property on a Java class.
- Parameters:
property
- the property
TypeDescriptor
protected TypeDescriptor(ResolvableType resolvableType, Class<?> type, Annotation[] annotations)
Create a new type descriptor from aResolvableType
. This protected constructor is used internally and may also be used by subclasses that support non-Java languages with extended type systems.- Parameters:
resolvableType
- the resolvable typetype
- the backing type (ornull
if it should get resolved)annotations
- the type annotations- Since:
- 4.0
Method Detail
getObjectType
public Class<?> getObjectType()
Variation ofgetType()
that accounts for a primitive type by returning its object wrapper type.This is useful for conversion service implementations that wish to normalize to object-based types and not work with primitive types directly.
getType
public Class<?> getType()
The type of the backing class, method parameter, field, or property described by this TypeDescriptor.Returns primitive types as-is. See
getObjectType()
for a variation of this operation that resolves primitive types to their corresponding Object types if necessary.- See Also:
getObjectType()
getResolvableType
public ResolvableType getResolvableType()
Return the underlyingResolvableType
.- Since:
- 4.0
getSource
public Object getSource()
Return the underlying source of the descriptor. Will return aField
,MethodParameter
orType
depending on how theTypeDescriptor
was constructed. This method is primarily to provide access to additional type information or meta-data that alternative JVM languages may provide.- Since:
- 4.0
narrow
public TypeDescriptor narrow(Object value)
Narrows thisTypeDescriptor
by setting its type to the class of the provided value.If the value is
null
, no narrowing is performed and this TypeDescriptor is returned unchanged.Designed to be called by binding frameworks when they read property, field, or method return values. Allows such frameworks to narrow a TypeDescriptor built from a declared property, field, or method return value type. For example, a field declared as
java.lang.Object
would be narrowed tojava.util.HashMap
if it was set to ajava.util.HashMap
value. The narrowed TypeDescriptor can then be used to convert the HashMap to some other type. Annotation and nested type context is preserved by the narrowed copy.- Parameters:
value
- the value to use for narrowing this type descriptor- Returns:
- this TypeDescriptor narrowed (returns a copy with its type updated to the class of the provided value)
upcast
public TypeDescriptor upcast(Class<?> superType)
Cast thisTypeDescriptor
to a superclass or implemented interface preserving annotations and nested type context.- Parameters:
superType
- the super type to cast to (can benull
)- Returns:
- a new TypeDescriptor for the up-cast type
- Throws:
IllegalArgumentException
- if this type is not assignable to the super-type- Since:
- 3.2
isPrimitive
public boolean isPrimitive()
Is this type a primitive type?
getAnnotations
public Annotation[] getAnnotations()
Return the annotations associated with this type descriptor, if any.- Returns:
- the annotations, or an empty array if none
hasAnnotation
public boolean hasAnnotation(Class<? extends Annotation> annotationType)
Determine if this type descriptor has the specified annotation.As of Spring Framework 4.2, this method supports arbitrary levels of meta-annotations.
- Parameters:
annotationType
- the annotation type- Returns:
- true if the annotation is present
getAnnotation
public <T extends Annotation> T getAnnotation(Class<T> annotationType)
Obtain the annotation of the specifiedannotationType
that is on this type descriptor.As of Spring Framework 4.2, this method supports arbitrary levels of meta-annotations.
- Parameters:
annotationType
- the annotation type- Returns:
- the annotation, or
null
if no such annotation exists on this type descriptor
isAssignableTo
public boolean isAssignableTo(TypeDescriptor typeDescriptor)
Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor.For example,
valueOf(String.class).isAssignableTo(valueOf(CharSequence.class))
returnstrue
because a String value can be assigned to a CharSequence variable. On the other hand,valueOf(Number.class).isAssignableTo(valueOf(Integer.class))
returnsfalse
because, while all Integers are Numbers, not all Numbers are Integers.For arrays, collections, and maps, element and key/value types are checked if declared. For example, a List<String> field value is assignable to a Collection<CharSequence> field, but List<Number> is not assignable to List<Integer>.
- Returns:
true
if this type is assignable to the type represented by the provided type descriptor- See Also:
getObjectType()
isCollection
public boolean isCollection()
Is this type aCollection
type?
isArray
public boolean isArray()
Is this type an array type?
getElementTypeDescriptor
public TypeDescriptor getElementTypeDescriptor()
If this type is an array, returns the array's component type. If this type is aStream
, returns the stream's component type. If this type is aCollection
and it is parameterized, returns the Collection's element type. If the Collection is not parameterized, returnsnull
indicating the element type is not declared.- Returns:
- the array component type or Collection element type, or
null
if this type is not an array type or ajava.util.Collection
or if its element type is not parameterized - See Also:
elementTypeDescriptor(Object)
elementTypeDescriptor
public TypeDescriptor elementTypeDescriptor(Object element)
If this type is aCollection
or an array, creates a element TypeDescriptor from the provided collection or array element.Narrows the
elementType
property to the class of the provided collection or array element. For example, if this describes ajava.util.List<java.lang.Number<
and the element argument is anjava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
. If this describes ajava.util.List<?>
and the element argument is anjava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
as well.Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
- Parameters:
element
- the collection or array element- Returns:
- a element type descriptor, narrowed to the type of the provided element
- See Also:
getElementTypeDescriptor()
,narrow(Object)
getMapKeyTypeDescriptor
public TypeDescriptor getMapKeyTypeDescriptor()
If this type is aMap
and its key type is parameterized, returns the map's key type. If the Map's key type is not parameterized, returnsnull
indicating the key type is not declared.- Returns:
- the Map key type, or
null
if this type is a Map but its key type is not parameterized - Throws:
IllegalStateException
- if this type is not ajava.util.Map
getMapKeyTypeDescriptor
public TypeDescriptor getMapKeyTypeDescriptor(Object mapKey)
If this type is aMap
, creates a mapKeyTypeDescriptor
from the provided map key.Narrows the
mapKeyType
property to the class of the provided map key. For example, if this describes ajava.util.Map<java.lang.Number, java.lang.String<
and the key argument is ajava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
. If this describes ajava.util.Map<?, ?>
and the key argument is ajava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
as well.Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
- Parameters:
mapKey
- the map key- Returns:
- the map key type descriptor
- Throws:
IllegalStateException
- if this type is not ajava.util.Map
- See Also:
narrow(Object)
getMapValueTypeDescriptor
public TypeDescriptor getMapValueTypeDescriptor()
If this type is aMap
and its value type is parameterized, returns the map's value type.If the Map's value type is not parameterized, returns
null
indicating the value type is not declared.- Returns:
- the Map value type, or
null
if this type is a Map but its value type is not parameterized - Throws:
IllegalStateException
- if this type is not ajava.util.Map
getMapValueTypeDescriptor
public TypeDescriptor getMapValueTypeDescriptor(Object mapValue)
If this type is aMap
, creates a mapValueTypeDescriptor
from the provided map value.Narrows the
mapValueType
property to the class of the provided map value. For example, if this describes ajava.util.Map<java.lang.String, java.lang.Number<
and the value argument is ajava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
. If this describes ajava.util.Map<?, ?>
and the value argument is ajava.lang.Integer
, the returned TypeDescriptor will bejava.lang.Integer
as well.Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
- Parameters:
mapValue
- the map value- Returns:
- the map value type descriptor
- Throws:
IllegalStateException
- if this type is not ajava.util.Map
- See Also:
narrow(Object)
forObject
public static TypeDescriptor forObject(Object source)
Create a new type descriptor for an object.Use this factory method to introspect a source object before asking the conversion system to convert it to some another type.
If the provided object is
null
, returnsnull
, else callsvalueOf(Class)
to build a TypeDescriptor from the object's class.- Parameters:
source
- the source object- Returns:
- the type descriptor
valueOf
public static TypeDescriptor valueOf(Class<?> type)
Create a new type descriptor from the given type.Use this to instruct the conversion system to convert an object to a specific target type, when no type location such as a method parameter or field is available to provide additional conversion context.
Generally prefer use of
forObject(Object)
for constructing type descriptors from source objects, as it handles thenull
object case.- Parameters:
type
- the class (may benull
to indicateObject.class
)- Returns:
- the corresponding type descriptor
collection
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementTypeDescriptor)
Create a new type descriptor from aCollection
type.Useful for converting to typed Collections.
For example, a
List<String>
could be converted to aList<EmailAddress>
by converting to a targetType built with this method. The method call to construct such aTypeDescriptor
would look something like:collection(List.class, TypeDescriptor.valueOf(EmailAddress.class));
- Parameters:
collectionType
- the collection type, which must implementCollection
.elementTypeDescriptor
- a descriptor for the collection's element type, used to convert collection elements- Returns:
- the collection type descriptor
map
public static TypeDescriptor map(Class<?> mapType, TypeDescriptor keyTypeDescriptor, TypeDescriptor valueTypeDescriptor)
Create a new type descriptor from aMap
type.Useful for converting to typed Maps.
For example, a Map<String, String> could be converted to a Map<Id, EmailAddress> by converting to a targetType built with this method: The method call to construct such a TypeDescriptor would look something like:
map(Map.class, TypeDescriptor.valueOf(Id.class), TypeDescriptor.valueOf(EmailAddress.class));
- Parameters:
mapType
- the map type, which must implementMap
keyTypeDescriptor
- a descriptor for the map's key type, used to convert map keysvalueTypeDescriptor
- the map's value type, used to convert map values- Returns:
- the map type descriptor
array
public static TypeDescriptor array(TypeDescriptor elementTypeDescriptor)
Create a new type descriptor as an array of the specified type.For example to create a
Map<String,String>[]
use:TypeDescriptor.array(TypeDescriptor.map(Map.class, TypeDescriptor.value(String.class), TypeDescriptor.value(String.class)));
- Parameters:
elementTypeDescriptor
- theTypeDescriptor
of the array element ornull
- Returns:
- an array
TypeDescriptor
ornull
ifelementTypeDescriptor
isnull
- Since:
- 3.2.1
nested
public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel)
Create a type descriptor for a nested type declared within the method parameter.For example, if the methodParameter is a
List<String>
and the nesting level is 1, the nested type descriptor will be String.class.If the methodParameter is a
List<List<String>>
and the nesting level is 2, the nested type descriptor will also be a String.class.If the methodParameter is a
Map<Integer, String>
and the nesting level is 1, the nested type descriptor will be String, derived from the map value.If the methodParameter is a
List<Map<Integer, String>>
and the nesting level is 2, the nested type descriptor will be String, derived from the map value.Returns
null
if a nested type cannot be obtained because it was not declared. For example, if the method parameter is aList<?>
, the nested type descriptor returned will benull
.- Parameters:
methodParameter
- the method parameter with a nestingLevel of 1nestingLevel
- the nesting level of the collection/array element or map key/value declaration within the method parameter- Returns:
- the nested type descriptor at the specified nesting level, or
null
if it could not be obtained - Throws:
IllegalArgumentException
- if the nesting level of the inputMethodParameter
argument is not 1, or if the types up to the specified nesting level are not of collection, array, or map types
nested
public static TypeDescriptor nested(Field field, int nestingLevel)
Create a type descriptor for a nested type declared within the field.For example, if the field is a
List<String>
and the nesting level is 1, the nested type descriptor will beString.class
.If the field is a
List<List<String>>
and the nesting level is 2, the nested type descriptor will also be aString.class
.If the field is a
Map<Integer, String>
and the nesting level is 1, the nested type descriptor will be String, derived from the map value.If the field is a
List<Map<Integer, String>>
and the nesting level is 2, the nested type descriptor will be String, derived from the map value.Returns
null
if a nested type cannot be obtained because it was not declared. For example, if the field is aList<?>
, the nested type descriptor returned will benull
.- Parameters:
field
- the fieldnestingLevel
- the nesting level of the collection/array element or map key/value declaration within the field- Returns:
- the nested type descriptor at the specified nesting level, or
null
if it could not be obtained - Throws:
IllegalArgumentException
- if the types up to the specified nesting level are not of collection, array, or map types
nested
public static TypeDescriptor nested(Property property, int nestingLevel)
Create a type descriptor for a nested type declared within the property.For example, if the property is a
List<String>
and the nesting level is 1, the nested type descriptor will beString.class
.If the property is a
List<List<String>>
and the nesting level is 2, the nested type descriptor will also be aString.class
.If the property is a
Map<Integer, String>
and the nesting level is 1, the nested type descriptor will be String, derived from the map value.If the property is a
List<Map<Integer, String>>
and the nesting level is 2, the nested type descriptor will be String, derived from the map value.Returns
null
if a nested type cannot be obtained because it was not declared. For example, if the property is aList<?>
, the nested type descriptor returned will benull
.- Parameters:
property
- the propertynestingLevel
- the nesting level of the collection/array element or map key/value declaration within the property- Returns:
- the nested type descriptor at the specified nesting level, or
null
if it could not be obtained - Throws:
IllegalArgumentException
- if the types up to the specified nesting level are not of collection, array, or map types