Class TypeDescriptor<T>

  • Type Parameters:
    T - the type represented by this TypeDescriptor
    All Implemented Interfaces:
    java.io.Serializable

    public abstract class TypeDescriptor<T>
    extends java.lang.Object
    implements java.io.Serializable
    A description of a Java type, including actual generic parameters where possible.

    To prevent losing actual type arguments due to erasure, create an anonymous subclass with concrete types:

    
     TypeDescriptor<List<String>> typeDescriptor = new TypeDescriptor<List<String>>() {};
     

    If the above were not an anonymous subclass, the type List<String> would be erased and unavailable at run time.

    See Also:
    Serialized Form
    • Constructor Detail

      • TypeDescriptor

        protected TypeDescriptor()
        Creates a TypeDescriptor representing the type parameter T. To use this constructor properly, the type parameter must be a concrete type, for example new TypeDescriptor<List<String>>(){}.
      • TypeDescriptor

        protected TypeDescriptor​(java.lang.Object instance)
        Creates a TypeDescriptor representing the type parameter T, which should resolve to a concrete type in the context of the class clazz.

        Unlike TypeDescriptor(Class) this will also use context's of the enclosing instances while attempting to resolve the type. This means that the types of any classes instantiated in the concrete instance should be resolvable.

      • TypeDescriptor

        protected TypeDescriptor​(java.lang.Class<?> clazz)
        Creates a TypeDescriptor representing the type parameter T, which should resolve to a concrete type in the context of the class clazz.
    • Method Detail

      • getType

        public java.lang.reflect.Type getType()
        Returns the Type represented by this TypeDescriptor.
      • getRawType

        public java.lang.Class<? super T> getRawType()
        Returns the Class underlying the Type represented by this TypeDescriptor.
      • getComponentType

        public @Nullable TypeDescriptor<?> getComponentType()
        Returns the component type if this type is an array type, otherwise returns null.
      • getSupertype

        public final TypeDescriptor<? super T> getSupertype​(java.lang.Class<? super T> superclass)
        Returns the generic form of a supertype.
      • isArray

        public final boolean isArray()
        Returns true if this type is known to be an array type.
      • getTypeParameter

        public final java.lang.reflect.TypeVariable<java.lang.Class<? super T>> getTypeParameter​(java.lang.String paramName)
        Returns a TypeVariable for the named type parameter. Throws IllegalArgumentException if a type variable by the requested type parameter is not found.

        For example, new TypeDescriptor<List>(){}.getTypeParameter("T") returns a TypeVariable<? super List> representing the formal type parameter T.

        Do not mistake the type parameters (formal type argument list) with the actual type arguments. For example, if a class Foo extends List<String>, it does not make sense to ask for a type parameter, because Foo does not have any.

      • isSupertypeOf

        public final boolean isSupertypeOf​(TypeDescriptor<?> source)
        Returns true if this type is assignable from the given type.
      • isSubtypeOf

        public final boolean isSubtypeOf​(TypeDescriptor<?> parent)
        Return true if this type is a subtype of the given type.
      • getArgumentTypes

        public java.util.List<TypeDescriptor<?>> getArgumentTypes​(java.lang.reflect.Method method)
        Returns a list of argument types for the given method, which must be a part of the class.
      • resolveType

        public TypeDescriptor<?> resolveType​(java.lang.reflect.Type type)
        Returns a TypeDescriptor representing the given type, with type variables resolved according to the specialization in this type.

        For example, consider the following class:

        
         class MyList implements List<String> { ... }
         

        The TypeDescriptor returned by

        
         TypeDescriptor.of(MyList.class)
             .resolveType(Mylist.class.getMethod("get", int.class).getGenericReturnType)
         
        will represent the type String.
      • getTypes

        public java.lang.Iterable<TypeDescriptor> getTypes()
        Returns a set of TypeDescriptor, one for each superclass as well as each interface implemented by this class.
      • getInterfaces

        public java.lang.Iterable<TypeDescriptor> getInterfaces()
        Returns a set of TypeDescriptors, one for each interface implemented by this class.
      • getClasses

        public java.lang.Iterable<TypeDescriptor> getClasses()
        Returns a set of TypeDescriptors, one for each superclass (including this class).
      • where

        public <X> TypeDescriptor<T> where​(TypeParameter<X> typeParameter,
                                           TypeDescriptor<X> typeDescriptor)
        Returns a new TypeDescriptor where the type variable represented by typeParameter are substituted by type. For example, it can be used to construct Map<K, V> for any K and V type:
        
         static <K, V> TypeDescriptor<Map<K, V>> mapOf(
             TypeDescriptor<K> keyType, TypeDescriptor<V> valueType) {
           return new TypeDescriptor<Map<K, V>>() {}
               .where(new TypeParameter<K>() {}, keyType)
               .where(new TypeParameter<V>() {}, valueType);
         }
         
        Type Parameters:
        X - The parameter type
        Parameters:
        typeParameter - the parameter type variable
        typeDescriptor - the actual type to substitute
      • hasUnresolvedParameters

        public boolean hasUnresolvedParameters()
        Returns whether this TypeDescriptor has any unresolved type parameters, as opposed to being a concrete type.

        For example:

        
         TypeDescriptor.of(new ArrayList<String>() {}.getClass()).hasUnresolvedTypeParameters()
           => false, because the anonymous class is instantiated with a concrete type
        
         class TestUtils {
           <T> ArrayList<T> createTypeErasedList() {
             return new ArrayList<T>() {};
           }
         }
        
         TypeDescriptor.of(TestUtils.<String>createTypeErasedList().getClass())
           => true, because the type variable T got type-erased and the anonymous ArrayList class
           is instantiated with an unresolved type variable T.
         
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • equals

        public boolean equals​(@Nullable java.lang.Object other)
        Two type descriptor are equal if and only if they represent the same type.
        Overrides:
        equals in class java.lang.Object
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object