Package org.springframework.core.convert

# 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
Constructor
Description
`TypeDescriptor(Field field)`
Create a new type descriptor from a `Field`.
`TypeDescriptor(Property property)`
Create a new type descriptor from a `Property`.
`TypeDescriptor(MethodParameter methodParameter)`
Create a new type descriptor from a `MethodParameter`.
`TypeDescriptor(ResolvableType resolvableType, Class<?> type, Annotation[] annotations)`
Create a new type descriptor from a `ResolvableType`.

## Method Summary

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 a `Collection` type.
`TypeDescriptor`
`elementTypeDescriptor(Object element)`
If this type is a `Collection` or an array, creates an 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>
T`
`getAnnotation(Class<T> annotationType)`
Obtain the annotation of the specified `annotationType` 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 a `Map` and its key type is parameterized, returns the map's key type.
`TypeDescriptor`
`getMapKeyTypeDescriptor(Object mapKey)`
If this type is a `Map`, creates a mapKey `TypeDescriptor` from the provided map key.
`TypeDescriptor`
`getMapValueTypeDescriptor()`
If this type is a `Map` and its value type is parameterized, returns the map's value type.
`TypeDescriptor`
`getMapValueTypeDescriptor(Object mapValue)`
If this type is a `Map`, creates a mapValue `TypeDescriptor` from the provided map value.
`String`
`getName()`
Return the name of this type: the fully qualified class name.
`Class<?>`
`getObjectType()`
Variation of `getType()` that accounts for a primitive type by returning its object wrapper type.
`ResolvableType`
`getResolvableType()`
Return the underlying `ResolvableType`.
`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 a `Collection` type?
`boolean`
`isMap()`
Is this type a `Map` type?
`boolean`
`isPrimitive()`
Is this type a primitive type?
`static TypeDescriptor`
`map(Class<?> mapType, TypeDescriptor keyTypeDescriptor, TypeDescriptor valueTypeDescriptor)`
Create a new type descriptor from a `Map` type.
`TypeDescriptor`
`narrow(Object value)`
Narrows this `TypeDescriptor` by setting its type to the class of the provided value.
`TypeDescriptor`
`nested(int nestingLevel)`
Create a type descriptor for a nested type declared within this descriptor.
`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 this `TypeDescriptor` 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.

### Methods inherited from class java.lang.Object

`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

## Constructor Details

### TypeDescriptor

public TypeDescriptor(MethodParameter methodParameter)
Create a new type descriptor from a `MethodParameter`.

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 a `Field`.

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 a `Property`.

Use this constructor when a source or target conversion point is a property on a Java class.

Parameters:
  `property` - the property

### TypeDescriptor

public TypeDescriptor(ResolvableType resolvableType, @Nullable Class<?> type, @Nullable Annotation[] annotations)
Create a new type descriptor from a `ResolvableType`.

This constructor is used internally and may also be used by subclasses that support non-Java languages with extended type systems. It is public as of 5.1.4 whereas it was protected before.

Parameters:
  `resolvableType` - the resolvable type
  `type` - the backing type (or `null` if it should get resolved)
  `annotations` - the type annotations
Since:
  4.0

## Method Details

### getObjectType

public Class<?> getObjectType()
Variation of `getType()` 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 underlying `ResolvableType`.

Since:
  4.0

### getSource

public Object getSource()
Return the underlying source of the descriptor. Will return a `Field`, `MethodParameter` or `Type` depending on how the `TypeDescriptor` 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

### nested

@Nullable public TypeDescriptor nested(int nestingLevel)
Create a type descriptor for a nested type declared within this descriptor.

Parameters:
  `nestingLevel` - 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
Since:
  6.1

### narrow

public TypeDescriptor narrow(@Nullable Object value)
Narrows this `TypeDescriptor` 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 to `java.util.HashMap` if it was set to a `java.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

@Nullable public TypeDescriptor upcast(@Nullable Class<?> superType)
Cast this `TypeDescriptor` to a superclass or implemented interface preserving annotations and nested type context.

Parameters:
  `superType` - the supertype to cast to (can be `null`)
Returns:
  a new TypeDescriptor for the up-cast type
Throws:
  `IllegalArgumentException` - if this type is not assignable to the super-type
Since:
  3.2

### getName

public String getName()
Return the name of this type: the fully qualified class name.

### 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

@Nullable public <T extends Annotation> T getAnnotation(Class<T> annotationType)
Obtain the annotation of the specified `annotationType` 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))` returns `true` because a String value can be assigned to a CharSequence variable. On the other hand, `valueOf(Number.class).isAssignableTo(valueOf(Integer.class))` returns `false` 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 a `Collection` type?

### isArray

public boolean isArray()
Is this type an array type?

### getElementTypeDescriptor

@Nullable public TypeDescriptor getElementTypeDescriptor()
If this type is an array, returns the array's component type. If this type is a `Stream`, returns the stream's component type. If this type is a `Collection` and it is parameterized, returns the Collection's element type. If the Collection is not parameterized, returns `null` 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 a `java.util.Collection` or if its element type is not parameterized
See Also:
  - `elementTypeDescriptor(Object)`

### elementTypeDescriptor

@Nullable public TypeDescriptor elementTypeDescriptor(Object element)
If this type is a `Collection` or an array, creates an 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 a `java.util.List<java.lang.Number>` and the element argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.lang.Integer`. If this describes a `java.util.List<?>` and the element argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.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:
  an element type descriptor, narrowed to the type of the provided element
See Also:
  - `getElementTypeDescriptor()`
  - `narrow(Object)`

### isMap

public boolean isMap()
Is this type a `Map` type?

### getMapKeyTypeDescriptor

@Nullable public TypeDescriptor getMapKeyTypeDescriptor()
If this type is a `Map` and its key type is parameterized, returns the map's key type. If the Map's key type is not parameterized, returns `null` 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 a `java.util.Map`

### getMapKeyTypeDescriptor

@Nullable public TypeDescriptor getMapKeyTypeDescriptor(Object mapKey)
If this type is a `Map`, creates a mapKey `TypeDescriptor` from the provided map key.

Narrows the `mapKeyType` property to the class of the provided map key. For example, if this describes a `java.util.Map<java.lang.Number, java.lang.String>` and the key argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.lang.Integer`. If this describes a `java.util.Map<?, ?>` and the key argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.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 a `java.util.Map`
See Also:
  - `narrow(Object)`

### getMapValueTypeDescriptor

@Nullable public TypeDescriptor getMapValueTypeDescriptor()
If this type is a `Map` 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 a `java.util.Map`

### getMapValueTypeDescriptor

@Nullable public TypeDescriptor getMapValueTypeDescriptor(@Nullable Object mapValue)
If this type is a `Map`, creates a mapValue `TypeDescriptor` from the provided map value.

Narrows the `mapValueType` property to the class of the provided map value. For example, if this describes a `java.util.Map<java.lang.String, java.lang.Number>` and the value argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.lang.Integer`. If this describes a `java.util.Map<?, ?>` and the value argument is a `java.lang.Integer`, the returned TypeDescriptor will be `java.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 a `java.util.Map`
See Also:
  - `narrow(Object)`

### equals

public boolean equals(@Nullable Object other)

Overrides:
  `equals` in class `Object`

### hashCode

public int hashCode()

Overrides:
  `hashCode` in class `Object`

### toString

public String toString()

Overrides:
  `toString` in class `Object`

### forObject

@Nullable @Contract("!null -> !null; null -> null") public static TypeDescriptor forObject(@Nullable 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 other type.

If the provided object is `null`, returns `null`, else calls `valueOf(Class)` to build a TypeDescriptor from the object's class.

Parameters:
  `source` - the source object
Returns:
  the type descriptor

### valueOf

public static TypeDescriptor valueOf(@Nullable 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 the `null` object case.

Parameters:
  `type` - the class (may be `null` to indicate `Object.class`)
Returns:
  the corresponding type descriptor

### collection

public static TypeDescriptor collection(Class<?> collectionType, @Nullable TypeDescriptor elementTypeDescriptor)
Create a new type descriptor from a `Collection` type.

Useful for converting to typed Collections.

For example, a `List<String>` could be converted to a `List<EmailAddress>` by converting to a targetType built with this method. The method call to construct such a `TypeDescriptor` would look something like: `collection(List.class, TypeDescriptor.valueOf(EmailAddress.class));`

Parameters:
  `collectionType` - the collection type, which must implement `Collection`.
  `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, @Nullable TypeDescriptor keyTypeDescriptor, @Nullable TypeDescriptor valueTypeDescriptor)
Create a new type descriptor from a `Map` 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 implement `Map`
  `keyTypeDescriptor` - a descriptor for the map's key type, used to convert map keys
  `valueTypeDescriptor` - the map's value type, used to convert map values
Returns:
  the map type descriptor

### array

@Nullable @Contract("!null -> !null; null -> null") public static TypeDescriptor array(@Nullable 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` - the `TypeDescriptor` of the array element or `null`
Returns:
  an array `TypeDescriptor` or `null` if `elementTypeDescriptor` is `null`
Since:
  3.2.1

### nested

@Nullable 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 a `List<?>`, the nested type descriptor returned will be `null`.

Parameters:
  `methodParameter` - the method parameter with a nestingLevel of 1
  `nestingLevel` - 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 input `MethodParameter` argument is not 1, or if the types up to the specified nesting level are not of collection, array, or map types

### nested

@Nullable 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 be `String.class`.

If the field is a `List<List<String>>` and the nesting level is 2, the nested type descriptor will also be a `String.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 a `List<?>`, the nested type descriptor returned will be `null`.

Parameters:
  `field` - the field
  `nestingLevel` - 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

@Nullable 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 be `String.class`.

If the property is a `List<List<String>>` and the nesting level is 2, the nested type descriptor will also be a `String.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 a `List<?>`, the nested type descriptor returned will be `null`.

Parameters:
  `property` - the property
  `nestingLevel` - 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