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

  Context about a type to convert from or to.
  Since:
    3.0
  Author:
    Keith Donald, Andy Clement, Juergen Hoeller, Phillip Webb, Sam Brannen
  See Also:
    Serialized Form

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `TypeDescriptor(Field field)` Create a new type descriptor from a `Field`.
    `TypeDescriptor(MethodParameter methodParameter)` Create a new type descriptor from a `MethodParameter`.
    `TypeDescriptor(Property property)` Create a new type descriptor from a `Property`.

  - ### Method Summary

    Methods
    Modifier and Type | Method and 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 a element TypeDescriptor from the provided collection or array element.
    `boolean` | `equals(Object obj)`
    `static TypeDescriptor` | `forObject(Object source)` Create a new type descriptor for an object.
    `<T extends Annotation> T` | `getAnnotation(Class<T> annotationType)` Obtain the annotation associated with this type descriptor of the specified type.
    `Annotation[]` | `getAnnotations()` The annotations associated with this type descriptor, if any.
    `Class<?>` | `getElementType()` Deprecated. in Spring 3.1 in favor of `getElementTypeDescriptor()`
    `TypeDescriptor` | `getElementTypeDescriptor()` If this type is an array, returns the array's component type.
    `Class<?>` | `getMapKeyType()` Deprecated. in Spring 3.1 in favor of `getMapKeyTypeDescriptor()`
    `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.
    `Class<?>` | `getMapValueType()` Deprecated. in Spring 3.1 in favor of `getMapValueTypeDescriptor()`
    `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()` Returns 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.
    `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.
    `static TypeDescriptor` | `nested(Field field, int nestingLevel)` Creates a type descriptor for a nested type declared within the field.
    `static TypeDescriptor` | `nested(MethodParameter methodParameter, int nestingLevel)` Creates a type descriptor for a nested type declared within the method parameter.
    `static TypeDescriptor` | `nested(Property property, int nestingLevel)` Creates a type descriptor for a nested type declared within the property.
    `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 Detail

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

  - ### Method Detail

    - #### 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 the `null` object case.

      Parameters:
        `type` - the class
      Returns:
        the type descriptor

    - #### collection

          public static TypeDescriptor collection(Class<?> collectionType,
                                  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,
                           TypeDescriptor keyTypeDescriptor,
                           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

          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` - the `TypeDescriptor` of the array element or `null`
      Returns:
        an array `TypeDescriptor` or `null` if `elementTypeDescriptor` is `null`
      Since:
        3.2.1

    - #### nested

          public static TypeDescriptor nested(MethodParameter methodParameter,
                              int nestingLevel)

      Creates 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
        `IllegalArgumentException` - 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)

      Creates 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

          public static TypeDescriptor nested(Property property,
                              int nestingLevel)

      Creates 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

    - #### 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, returns null, else calls `valueOf(Class)` to build a TypeDescriptor from the object's class.

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

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

      Returns:
        the type, or `null`
      See Also:
        `getObjectType()`

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

    - #### narrow

          public TypeDescriptor narrow(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

          public TypeDescriptor upcast(Class<?> superType)

      Cast this `TypeDescriptor` to a superclass or implemented interface preserving annotations and nested type context.
      Parameters:
        `superType` - the super type 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()

      Returns the name of this type: the fully qualified class name.

    - #### isPrimitive

          public boolean isPrimitive()

      Is this type a primitive type?

    - #### getAnnotations

          public Annotation[] getAnnotations()

      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.
      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 associated with this type descriptor of the specified type.
      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

          public TypeDescriptor getElementTypeDescriptor()

      If this type is an array, returns the array'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 a Collection but its element type is not parameterized
      Throws:
        `IllegalStateException` - if this type is not a java.util.Collection or Array type

    - #### elementTypeDescriptor

          public TypeDescriptor elementTypeDescriptor(Object element)

      If this type is a `Collection` 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 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:
        a element type descriptor, narrowed to the type of the provided element
      Throws:
        `IllegalStateException` - if this type is not a java.util.Collection or Array type
      See Also:
        `narrow(Object)`

    - #### isMap

          public boolean isMap()

      Is this type a `Map` type?

    - #### getMapKeyTypeDescriptor

          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

          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

          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

          public TypeDescriptor getMapValueTypeDescriptor(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

    - #### getElementType

          @Deprecated
          public Class<?> getElementType()

      Deprecated. in Spring 3.1 in favor of `getElementTypeDescriptor()`
      Returns the value of `getType()` for the `elementTypeDescriptor`.
      Throws:
        `IllegalStateException` - if this type is not a java.util.Collection or Array type

    - #### getMapKeyType

          @Deprecated
          public Class<?> getMapKeyType()

      Deprecated. in Spring 3.1 in favor of `getMapKeyTypeDescriptor()`
      Returns the value of `getType()` for the `getMapKeyTypeDescriptor`.
      Throws:
        `IllegalStateException` - if this type is not a java.util.Map

    - #### getMapValueType

          @Deprecated
          public Class<?> getMapValueType()

      Deprecated. in Spring 3.1 in favor of `getMapValueTypeDescriptor()`
      Returns the value of `getType()` for the `getMapValueTypeDescriptor`.
      Throws:
        `IllegalStateException` - if this type is not a java.util.Map

    - #### equals

          public boolean equals(Object obj)

      Overrides:
        `equals` in class `Object`

    - #### hashCode

          public int hashCode()

      Overrides:
        `hashCode` in class `Object`

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`