Class TypeToken<T>

  • All Implemented Interfaces:
    java.io.Serializable
    Direct Known Subclasses:
    TypeToken.SimpleTypeToken

    @Beta
    public abstract class TypeToken<T>
    extends TypeCapture<T>
    implements java.io.Serializable
    A Type with generics.

    Operations that are otherwise only available in Class are implemented to support Type, for example isSubtypeOf(com.google.common.reflect.TypeToken<?>), isArray() and getComponentType(). It also provides additional utilities such as getTypes(), resolveType(java.lang.reflect.Type), etc.

    There are three ways to get a TypeToken instance:

    • Wrap a Type obtained via reflection. For example: TypeToken.of(method.getGenericReturnType()).
    • Capture a generic type with a (usually anonymous) subclass. For example:
         
         new TypeToken<List<String>>() {}

      Note that it's critical that the actual type argument is carried by a subclass. The following code is wrong because it only captures the <T> type variable of the listType() method signature; while <String> is lost in erasure:

         
         class Util {
           static <T> TypeToken<List<T>> listType() {
             return new TypeToken<List<T>>() {};
           }
         }
      
         TypeToken<List<String>> stringListType = Util.<String>listType();
    • Capture a generic type with a (usually anonymous) subclass and resolve it against a context class that knows what the type parameters are. For example:
         
         abstract class IKnowMyType<T> {
           TypeToken<T> type = new TypeToken<T>(getClass()) {};
         }
         new IKnowMyType<String>() {}.type => String

    TypeToken is serializable when no type variable is contained in the type.

    Note to Guice users: TypeToken is similar to Guice's TypeLiteral class except that it is serializable and offers numerous additional utility methods.

    Since:
    12.0
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected TypeToken()
      Constructs a new type token of T.
      protected TypeToken​(java.lang.Class<?> declaringClass)
      Constructs a new type token of T while resolving free type variables in the context of declaringClass.
      private TypeToken​(java.lang.reflect.Type type)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private static TypeToken.Bounds any​(java.lang.reflect.Type[] bounds)  
      private TypeToken<? super T> boundAsSuperclass​(java.lang.reflect.Type bound)  
      private ImmutableList<TypeToken<? super T>> boundsAsInterfaces​(java.lang.reflect.Type[] bounds)  
      Invokable<T,​T> constructor​(java.lang.reflect.Constructor<?> constructor)
      Returns the Invokable for constructor, which must be a member of T.
      boolean equals​(java.lang.Object o)
      Returns true if o is another TypeToken that represents the same Type.
      private static TypeToken.Bounds every​(java.lang.reflect.Type[] bounds)  
      private TypeToken<? extends T> getArraySubtype​(java.lang.Class<?> subclass)  
      private TypeToken<? super T> getArraySupertype​(java.lang.Class<? super T> supertype)  
      TypeToken<?> getComponentType()
      Returns the array component type if this type represents an array (int[], T[], <? extends Map<String, Integer>[]> etc.), or else null is returned.
      (package private) ImmutableList<TypeToken<? super T>> getGenericInterfaces()
      Returns the generic interfaces that this type directly implements.
      (package private) TypeToken<? super T> getGenericSuperclass()
      Returns the generic superclass of this type or null if the type represents Object or an interface.
      private java.lang.reflect.Type getOwnerTypeIfPresent()
      Returns the owner type of a ParameterizedType or enclosing class of a Class, or null otherwise.
      java.lang.Class<? super T> getRawType()
      Returns the raw type of T.
      private ImmutableSet<java.lang.Class<? super T>> getRawTypes()  
      TypeToken<? extends T> getSubtype​(java.lang.Class<?> subclass)
      Returns subtype of this with subclass as the raw class.
      private TypeToken<? extends T> getSubtypeFromLowerBounds​(java.lang.Class<?> subclass, java.lang.reflect.Type[] lowerBounds)  
      TypeToken<? super T> getSupertype​(java.lang.Class<? super T> superclass)
      Returns the generic form of superclass.
      private TypeToken<? super T> getSupertypeFromUpperBounds​(java.lang.Class<? super T> supertype, java.lang.reflect.Type[] upperBounds)  
      java.lang.reflect.Type getType()
      Returns the represented type.
      TypeToken.TypeSet getTypes()
      Returns the set of interfaces and classes that this type is or is a subtype of.
      int hashCode()  
      private boolean is​(java.lang.reflect.Type formalType)
      Return true if any of the following conditions is met: 'this' and formalType are equal formalType is <? extends Foo> and 'this' is a subtype of Foo formalType is <? super Foo> and 'this' is a supertype of Foo
      boolean isArray()
      Returns true if this type is known to be an array type, such as int[], T[], <? extends Map<String, Integer>[]> etc.
      private boolean isOwnedBySubtypeOf​(java.lang.reflect.Type supertype)  
      boolean isPrimitive()
      Returns true if this type is one of the nine primitive types (including void).
      boolean isSubtypeOf​(TypeToken<?> type)
      Returns true if this type is a subtype of the given type.
      boolean isSubtypeOf​(java.lang.reflect.Type supertype)
      Returns true if this type is a subtype of the given type.
      private boolean isSubtypeOfArrayType​(java.lang.reflect.GenericArrayType supertype)  
      private boolean isSubtypeOfParameterizedType​(java.lang.reflect.ParameterizedType supertype)  
      boolean isSupertypeOf​(TypeToken<?> type)
      Returns true if this type is a supertype of the given type.
      boolean isSupertypeOf​(java.lang.reflect.Type type)
      Returns true if this type is a supertype of the given type.
      private boolean isSupertypeOfArray​(java.lang.reflect.GenericArrayType subtype)  
      private boolean isWrapper()  
      Invokable<T,​java.lang.Object> method​(java.lang.reflect.Method method)
      Returns the Invokable for method, which must be a member of T.
      private static java.lang.reflect.Type newArrayClassOrGenericArrayType​(java.lang.reflect.Type componentType)
      Creates an array class if componentType is a class, or else, a GenericArrayType.
      static <T> TypeToken<T> of​(java.lang.Class<T> type)
      Returns an instance of type token that wraps type.
      static TypeToken<?> of​(java.lang.reflect.Type type)
      Returns an instance of type token that wraps type.
      (package private) TypeToken<T> rejectTypeVariables()
      Ensures that this type token doesn't contain type variables, which can cause unchecked type errors for callers like TypeToInstanceMap.
      private java.lang.reflect.Type[] resolveInPlace​(java.lang.reflect.Type[] types)  
      private TypeToken<?> resolveSupertype​(java.lang.reflect.Type type)  
      TypeToken<?> resolveType​(java.lang.reflect.Type type)
      Resolves the given type against the type context represented by this type.
      private java.lang.reflect.Type resolveTypeArgsForSubclass​(java.lang.Class<?> subclass)  
      private boolean someRawTypeIsSubclassOf​(java.lang.Class<?> superclass)  
      (package private) static <T> TypeToken<? extends T> toGenericType​(java.lang.Class<T> cls)
      Returns the type token representing the generic type declaration of cls.
      java.lang.String toString()  
      TypeToken<T> unwrap()
      Returns the corresponding primitive type if this is a wrapper type; otherwise returns this itself.
      <X> TypeToken<T> where​(TypeParameter<X> typeParam, TypeToken<X> typeArg)
      Returns a new TypeToken where type variables represented by typeParam are substituted by typeArg.
      <X> TypeToken<T> where​(TypeParameter<X> typeParam, java.lang.Class<X> typeArg)
      Returns a new TypeToken where type variables represented by typeParam are substituted by typeArg.
      TypeToken<T> wrap()
      Returns the corresponding wrapper type if this is a primitive type; otherwise returns this itself.
      protected java.lang.Object writeReplace()
      Implemented to support serialization of subclasses.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, wait, wait, wait
    • Field Detail

      • runtimeType

        private final java.lang.reflect.Type runtimeType
      • typeResolver

        private transient TypeResolver typeResolver
        Resolver for resolving types with runtimeType as context.
    • Constructor Detail

      • TypeToken

        protected TypeToken()
        Constructs a new type token of T.

        Clients create an empty anonymous subclass. Doing so embeds the type parameter in the anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.

        For example:

           
           TypeToken<List<String>> t = new TypeToken<List<String>>() {};
      • TypeToken

        protected TypeToken​(java.lang.Class<?> declaringClass)
        Constructs a new type token of T while resolving free type variables in the context of declaringClass.

        Clients create an empty anonymous subclass. Doing so embeds the type parameter in the anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.

        For example:

           
           abstract class IKnowMyType<T> {
             TypeToken<T> getMyType() {
               return new TypeToken<T>(getClass()) {};
             }
           }
        
           new IKnowMyType<String>() {}.getMyType() => String
      • TypeToken

        private TypeToken​(java.lang.reflect.Type type)
    • Method Detail

      • of

        public static <T> TypeToken<T> of​(java.lang.Class<T> type)
        Returns an instance of type token that wraps type.
      • of

        public static TypeToken<?> of​(java.lang.reflect.Type type)
        Returns an instance of type token that wraps type.
      • getRawType

        public final java.lang.Class<? super T> getRawType()
        Returns the raw type of T. Formally speaking, if T is returned by Method.getGenericReturnType(), the raw type is what's returned by Method.getReturnType() of the same method object. Specifically:
        • If T is a Class itself, T itself is returned.
        • If T is a ParameterizedType, the raw type of the parameterized type is returned.
        • If T is a GenericArrayType, the returned type is the corresponding array class. For example: List<Integer>[] => List[].
        • If T is a type variable or a wildcard type, the raw type of the first upper bound is returned. For example: <X extends Foo> => Foo.
      • getType

        public final java.lang.reflect.Type getType()
        Returns the represented type.
      • where

        public final <X> TypeToken<T> where​(TypeParameter<X> typeParam,
                                            TypeToken<X> typeArg)

        Returns a new TypeToken where type variables represented by typeParam are substituted by typeArg. For example, it can be used to construct Map<K, V> for any K and V type:

           
           static <K, V> TypeToken<Map<K, V>> mapOf(
               TypeToken<K> keyType, TypeToken<V> valueType) {
             return new TypeToken<Map<K, V>>() {}
                 .where(new TypeParameter<K>() {}, keyType)
                 .where(new TypeParameter<V>() {}, valueType);
           }
        Type Parameters:
        X - The parameter type
        Parameters:
        typeParam - the parameter type variable
        typeArg - the actual type to substitute
      • where

        public final <X> TypeToken<T> where​(TypeParameter<X> typeParam,
                                            java.lang.Class<X> typeArg)

        Returns a new TypeToken where type variables represented by typeParam are substituted by typeArg. For example, it can be used to construct Map<K, V> for any K and V type:

           
           static <K, V> TypeToken<Map<K, V>> mapOf(
               Class<K> keyType, Class<V> valueType) {
             return new TypeToken<Map<K, V>>() {}
                 .where(new TypeParameter<K>() {}, keyType)
                 .where(new TypeParameter<V>() {}, valueType);
           }
        Type Parameters:
        X - The parameter type
        Parameters:
        typeParam - the parameter type variable
        typeArg - the actual type to substitute
      • resolveType

        public final TypeToken<?> resolveType​(java.lang.reflect.Type type)

        Resolves the given type against the type context represented by this type. For example:

           
           new TypeToken<List<String>>() {}.resolveType(
               List.class.getMethod("get", int.class).getGenericReturnType())
           => String.class
      • resolveInPlace

        private java.lang.reflect.Type[] resolveInPlace​(java.lang.reflect.Type[] types)
      • resolveSupertype

        private TypeToken<?> resolveSupertype​(java.lang.reflect.Type type)
      • getGenericSuperclass

        @Nullable
        final TypeToken<? super T> getGenericSuperclass()
        Returns the generic superclass of this type or null if the type represents Object or an interface. This method is similar but different from Class.getGenericSuperclass(). For example, new TypeToken<StringArrayList>() {}.getGenericSuperclass() will return new TypeToken<ArrayList<String>>() {}; while StringArrayList.class.getGenericSuperclass() will return ArrayList<E>, where E is the type variable declared by class ArrayList.

        If this type is a type variable or wildcard, its first upper bound is examined and returned if the bound is a class or extends from a class. This means that the returned type could be a type variable too.

      • boundAsSuperclass

        @Nullable
        private TypeToken<? super T> boundAsSuperclass​(java.lang.reflect.Type bound)
      • getGenericInterfaces

        final ImmutableList<TypeToken<? super T>> getGenericInterfaces()
        Returns the generic interfaces that this type directly implements. This method is similar but different from Class.getGenericInterfaces(). For example, new TypeToken<List<String>>() {}.getGenericInterfaces() will return a list that contains new TypeToken<Iterable<String>>() {}; while List.class.getGenericInterfaces() will return an array that contains Iterable<T>, where the T is the type variable declared by interface Iterable.

        If this type is a type variable or wildcard, its upper bounds are examined and those that are either an interface or upper-bounded only by interfaces are returned. This means that the returned types could include type variables too.

      • boundsAsInterfaces

        private ImmutableList<TypeToken<? super T>> boundsAsInterfaces​(java.lang.reflect.Type[] bounds)
      • getTypes

        public final TypeToken.TypeSet getTypes()
        Returns the set of interfaces and classes that this type is or is a subtype of. The returned types are parameterized with proper type arguments.

        Subtypes are always listed before supertypes. But the reverse is not true. A type isn't necessarily a subtype of all the types following. Order between types without subtype relationship is arbitrary and not guaranteed.

        If this type is a type variable or wildcard, upper bounds that are themselves type variables aren't included (their super interfaces and superclasses are).

      • getSupertype

        public final TypeToken<? super T> getSupertype​(java.lang.Class<? super T> superclass)
        Returns the generic form of superclass. For example, if this is ArrayList<String>, Iterable<String> is returned given the input Iterable.class.
      • getSubtype

        public final TypeToken<? extends T> getSubtype​(java.lang.Class<?> subclass)
        Returns subtype of this with subclass as the raw class. For example, if this is Iterable<String> and subclass is List, List<String> is returned.
      • isSupertypeOf

        public final boolean isSupertypeOf​(TypeToken<?> type)
        Returns true if this type is a supertype of the given type. "Supertype" is defined according to the rules for type arguments introduced with Java generics.
        Since:
        19.0
      • isSupertypeOf

        public final boolean isSupertypeOf​(java.lang.reflect.Type type)
        Returns true if this type is a supertype of the given type. "Supertype" is defined according to the rules for type arguments introduced with Java generics.
        Since:
        19.0
      • isSubtypeOf

        public final boolean isSubtypeOf​(TypeToken<?> type)
        Returns true if this type is a subtype of the given type. "Subtype" is defined according to the rules for type arguments introduced with Java generics.
        Since:
        19.0
      • isSubtypeOf

        public final boolean isSubtypeOf​(java.lang.reflect.Type supertype)
        Returns true if this type is a subtype of the given type. "Subtype" is defined according to the rules for type arguments introduced with Java generics.
        Since:
        19.0
      • isArray

        public final boolean isArray()
        Returns true if this type is known to be an array type, such as int[], T[], <? extends Map<String, Integer>[]> etc.
      • isPrimitive

        public final boolean isPrimitive()
        Returns true if this type is one of the nine primitive types (including void).
        Since:
        15.0
      • wrap

        public final TypeToken<T> wrap()
        Returns the corresponding wrapper type if this is a primitive type; otherwise returns this itself. Idempotent.
        Since:
        15.0
      • isWrapper

        private boolean isWrapper()
      • unwrap

        public final TypeToken<T> unwrap()
        Returns the corresponding primitive type if this is a wrapper type; otherwise returns this itself. Idempotent.
        Since:
        15.0
      • getComponentType

        @Nullable
        public final TypeToken<?> getComponentType()
        Returns the array component type if this type represents an array (int[], T[], <? extends Map<String, Integer>[]> etc.), or else null is returned.
      • method

        public final Invokable<T,​java.lang.Object> method​(java.lang.reflect.Method method)
        Returns the Invokable for method, which must be a member of T.
        Since:
        14.0
      • constructor

        public final Invokable<T,​T> constructor​(java.lang.reflect.Constructor<?> constructor)
        Returns the Invokable for constructor, which must be a member of T.
        Since:
        14.0
      • equals

        public boolean equals​(@Nullable
                              java.lang.Object o)
        Returns true if o is another TypeToken that represents the same Type.
        Overrides:
        equals in class java.lang.Object
      • hashCode

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

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

        protected java.lang.Object writeReplace()
        Implemented to support serialization of subclasses.
      • rejectTypeVariables

        final TypeToken<T> rejectTypeVariables()
        Ensures that this type token doesn't contain type variables, which can cause unchecked type errors for callers like TypeToInstanceMap.
      • someRawTypeIsSubclassOf

        private boolean someRawTypeIsSubclassOf​(java.lang.Class<?> superclass)
      • isSubtypeOfParameterizedType

        private boolean isSubtypeOfParameterizedType​(java.lang.reflect.ParameterizedType supertype)
      • isSubtypeOfArrayType

        private boolean isSubtypeOfArrayType​(java.lang.reflect.GenericArrayType supertype)
      • isSupertypeOfArray

        private boolean isSupertypeOfArray​(java.lang.reflect.GenericArrayType subtype)
      • is

        private boolean is​(java.lang.reflect.Type formalType)
        Return true if any of the following conditions is met:
        • 'this' and formalType are equal
        • formalType is <? extends Foo> and 'this' is a subtype of Foo
        • formalType is <? super Foo> and 'this' is a supertype of Foo
      • every

        private static TypeToken.Bounds every​(java.lang.reflect.Type[] bounds)
      • any

        private static TypeToken.Bounds any​(java.lang.reflect.Type[] bounds)
      • getRawTypes

        private ImmutableSet<java.lang.Class<? super T>> getRawTypes()
      • isOwnedBySubtypeOf

        private boolean isOwnedBySubtypeOf​(java.lang.reflect.Type supertype)
      • getOwnerTypeIfPresent

        @Nullable
        private java.lang.reflect.Type getOwnerTypeIfPresent()
        Returns the owner type of a ParameterizedType or enclosing class of a Class, or null otherwise.
      • toGenericType

        static <T> TypeToken<? extends T> toGenericType​(java.lang.Class<T> cls)
        Returns the type token representing the generic type declaration of cls. For example: TypeToken.getGenericType(Iterable.class) returns Iterable<T>.

        If cls isn't parameterized and isn't a generic array, the type token of the class is returned.

      • getSupertypeFromUpperBounds

        private TypeToken<? super T> getSupertypeFromUpperBounds​(java.lang.Class<? super T> supertype,
                                                                 java.lang.reflect.Type[] upperBounds)
      • getSubtypeFromLowerBounds

        private TypeToken<? extends T> getSubtypeFromLowerBounds​(java.lang.Class<?> subclass,
                                                                 java.lang.reflect.Type[] lowerBounds)
      • getArraySupertype

        private TypeToken<? super T> getArraySupertype​(java.lang.Class<? super T> supertype)
      • getArraySubtype

        private TypeToken<? extends T> getArraySubtype​(java.lang.Class<?> subclass)
      • resolveTypeArgsForSubclass

        private java.lang.reflect.Type resolveTypeArgsForSubclass​(java.lang.Class<?> subclass)
      • newArrayClassOrGenericArrayType

        private static java.lang.reflect.Type newArrayClassOrGenericArrayType​(java.lang.reflect.Type componentType)
        Creates an array class if componentType is a class, or else, a GenericArrayType. This is what Java7 does for generic array type parameters.