Class TypeToken<T>
- All Implemented Interfaces:
Serializable
- Direct Known Subclasses:
TypeToken.SimpleTypeToken
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
Typeobtained 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 thelistType()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:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classprivate final classprivate final classprivate static final classprivate static classCollects parent types from a subtype.private static enumclassThe set of interfaces and classes thatTis or is a subtype of. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate TypeResolverResolver for resolving covariant types withruntimeTypeas context.private TypeResolverResolver for resolving parameter and field types withruntimeTypeas context.private final Typeprivate static final long -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static TypeToken.BoundsboundAsSuperclass(Type bound) private ImmutableList<TypeToken<? super T>>boundsAsInterfaces(Type[] bounds) private static TypecanonicalizeTypeArg(TypeVariable<?> declaration, Type typeArg) In reflection,Foo<?>.getUpperBounds()[0]is alwaysObject.class, even when Foo is defined asFoo<T extends String>.private static ParameterizedTypeprivate static Typeprivate static WildcardTypecanonicalizeWildcardType(TypeVariable<?> declaration, WildcardType type) constructor(Constructor<?> constructor) booleanprivate static TypeToken.BoundsgetArraySubtype(Class<?> subclass) getArraySupertype(Class<? super T> supertype) final TypeToken<?>Returns the array component type if this type represents an array (int[],T[],<? extends Map<String, Integer>[]>etc.), or elsenullis returned.private TypeResolver(package private) final ImmutableList<TypeToken<? super T>>Returns the generic interfaces that this type directlyimplements.Returns the generic superclass of this type ornullif the type representsObjector an interface.private TypeResolverprivate TypeReturns the owner type of aParameterizedTypeor enclosing class of aClass, or null otherwise.Returns the raw type ofT.private ImmutableSet<Class<? super T>>getSubtype(Class<?> subclass) Returns subtype ofthiswithsubclassas the raw class.getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) getSupertype(Class<? super T> superclass) Returns the generic form ofsuperclass.getSupertypeFromUpperBounds(Class<? super T> supertype, Type[] upperBounds) final TypegetType()Returns the represented type.getTypes()Returns the set of interfaces and classes that this type is or is a subtype of.inthashCode()private booleanis(Type formalType, TypeVariable<?> declaration) A.is(B)is defined asFoo<A>.isSubtypeOf(Foo<B>).final booleanisArray()Returns true if this type is known to be an array type, such asint[],T[],<? extends Map<String, Integer>[]>etc.private booleanisOwnedBySubtypeOf(Type supertype) final booleanReturns true if this type is one of the nine primitive types (includingvoid).final booleanisSubtypeOf(TypeToken<?> type) Returns true if this type is a subtype of the giventype.final booleanisSubtypeOf(Type supertype) Returns true if this type is a subtype of the giventype.private booleanisSubtypeOfArrayType(GenericArrayType supertype) private booleanisSubtypeOfParameterizedType(ParameterizedType supertype) final booleanisSupertypeOf(TypeToken<?> type) Returns true if this type is a supertype of the giventype.final booleanisSupertypeOf(Type type) Returns true if this type is a supertype of the giventype.private booleanisSupertypeOfArray(GenericArrayType subtype) private booleanprivate static TypenewArrayClassOrGenericArrayType(Type componentType) Creates an array class ifcomponentTypeis a class, or else, aGenericArrayType.static <T> TypeToken<T>Returns an instance of type token that wrapstype.static TypeToken<?>Returns an instance of type token that wrapstype.Ensures that this type token doesn't contain type variables, which can cause unchecked type errors for callers likeTypeToInstanceMap.private TypeToken<?>resolveSupertype(Type type) final TypeToken<?>resolveType(Type type) Resolves the giventypeagainst the type context represented by this type.private TyperesolveTypeArgsForSubclass(Class<?> subclass) private booleansomeRawTypeIsSubclassOf(Class<?> superclass) (package private) static <T> TypeToken<? extends T>toGenericType(Class<T> cls) Returns the type token representing the generic type declaration ofcls.toString()unwrap()Returns the corresponding primitive type if this is a wrapper type; otherwise returnsthisitself.where(TypeParameter<X> typeParam, TypeToken<X> typeArg) Returns a newTypeTokenwhere type variables represented bytypeParamare substituted bytypeArg.where(TypeParameter<X> typeParam, Class<X> typeArg) Returns a newTypeTokenwhere type variables represented bytypeParamare substituted bytypeArg.wrap()Returns the corresponding wrapper type if this is a primitive type; otherwise returnsthisitself.protected ObjectImplemented to support serialization of subclasses.Methods inherited from class com.google.common.reflect.TypeCapture
capture
-
Field Details
-
runtimeType
-
invariantTypeResolver
Resolver for resolving parameter and field types withruntimeTypeas context. -
covariantTypeResolver
Resolver for resolving covariant types withruntimeTypeas context. -
serialVersionUID
private static final long serialVersionUID- See Also:
-
-
Constructor Details
-
TypeToken
protected TypeToken()Constructs a new type token ofT.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
Constructs a new type token ofTwhile resolving free type variables in the context ofdeclaringClass.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
-
-
Method Details
-
of
Returns an instance of type token that wrapstype. -
of
Returns an instance of type token that wrapstype. -
getRawType
Returns the raw type ofT. Formally speaking, ifTis returned byMethod.getGenericReturnType(), the raw type is what's returned byMethod.getReturnType()of the same method object. Specifically:- If
Tis aClassitself,Titself is returned. - If
Tis aParameterizedType, the raw type of the parameterized type is returned. - If
Tis aGenericArrayType, the returned type is the corresponding array class. For example:List<Integer>[] => List[]. - If
Tis a type variable or a wildcard type, the raw type of the first upper bound is returned. For example:<X extends Foo> => Foo.
- If
-
getType
Returns the represented type. -
where
Returns a newTypeTokenwhere type variables represented bytypeParamare substituted bytypeArg. For example, it can be used to constructMap<K, V>for anyKandVtype: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 variabletypeArg- the actual type to substitute
-
where
Returns a newTypeTokenwhere type variables represented bytypeParamare substituted bytypeArg. For example, it can be used to constructMap<K, V>for anyKandVtype: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 variabletypeArg- the actual type to substitute
-
resolveType
Resolves the giventypeagainst the type context represented by this type. For example:new TypeToken<List<String>>() {}.resolveType( List.class.getMethod("get", int.class).getGenericReturnType()) => String.class -
resolveSupertype
-
getGenericSuperclass
Returns the generic superclass of this type ornullif the type representsObjector an interface. This method is similar but different fromClass.getGenericSuperclass(). For example,new TypeToken<StringArrayList>() {}.getGenericSuperclass()will returnnew TypeToken<ArrayList<String>>() {}; whileStringArrayList.class.getGenericSuperclass()will returnArrayList<E>, whereEis the type variable declared by classArrayList.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
-
getGenericInterfaces
Returns the generic interfaces that this type directlyimplements. This method is similar but different fromClass.getGenericInterfaces(). For example,new TypeToken<List<String>>() {}.getGenericInterfaces()will return a list that containsnew TypeToken<Iterable<String>>() {}; whileList.class.getGenericInterfaces()will return an array that containsIterable<T>, where theTis the type variable declared by interfaceIterable.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
-
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
Returns the generic form ofsuperclass. For example, if this isArrayList<String>,Iterable<String>is returned given the inputIterable.class. -
getSubtype
Returns subtype ofthiswithsubclassas the raw class. For example, if this isIterable<String>andsubclassisList,List<String>is returned. -
isSupertypeOf
Returns true if this type is a supertype of the giventype. "Supertype" is defined according to the rules for type arguments introduced with Java generics.- Since:
- 19.0
-
isSupertypeOf
Returns true if this type is a supertype of the giventype. "Supertype" is defined according to the rules for type arguments introduced with Java generics.- Since:
- 19.0
-
isSubtypeOf
Returns true if this type is a subtype of the giventype. "Subtype" is defined according to the rules for type arguments introduced with Java generics.- Since:
- 19.0
-
isSubtypeOf
Returns true if this type is a subtype of the giventype. "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 asint[],T[],<? extends Map<String, Integer>[]>etc. -
isPrimitive
public final boolean isPrimitive()Returns true if this type is one of the nine primitive types (includingvoid).- Since:
- 15.0
-
wrap
Returns the corresponding wrapper type if this is a primitive type; otherwise returnsthisitself. Idempotent.- Since:
- 15.0
-
isWrapper
private boolean isWrapper() -
unwrap
Returns the corresponding primitive type if this is a wrapper type; otherwise returnsthisitself. Idempotent.- Since:
- 15.0
-
getComponentType
Returns the array component type if this type represents an array (int[],T[],<? extends Map<String, Integer>[]>etc.), or elsenullis returned. -
method
- Since:
- 14.0
-
constructor
- Since:
- 14.0
-
equals
-
hashCode
public int hashCode() -
toString
-
writeReplace
Implemented to support serialization of subclasses. -
rejectTypeVariables
Ensures that this type token doesn't contain type variables, which can cause unchecked type errors for callers likeTypeToInstanceMap. -
someRawTypeIsSubclassOf
-
isSubtypeOfParameterizedType
-
isSubtypeOfArrayType
-
isSupertypeOfArray
-
is
A.is(B)is defined asFoo<A>.isSubtypeOf(Foo<B>).Specifically, returns true if any of the following conditions is met:
- 'this' and
formalTypeare equal. - 'this' and
formalTypehave equal canonical form. formalTypeis<? extends Foo>and 'this' is a subtype ofFoo.formalTypeis<? super Foo>and 'this' is a supertype ofFoo.
Enum<? extends Enum<E>>canonicalizes toEnum<?>whereEis the type variable declared on theEnumclass declaration. It's technically not true thatFoo<Enum<? extends Enum<E>>>is a subtype ofFoo<Enum<?>>according to JLS. See testRecursiveWildcardSubtypeBug() for a real example.It appears that properly handling recursive type bounds in the presence of implicit type bounds is not easy. For now we punt, hoping that this defect should rarely cause issues in real code.
- Parameters:
formalType- isFoo<formalType>a supertype ofFoo<T>?declaration- The type variable in the context of a parameterized type. Used to infer type bound whenformalTypeis a wildcard with implicit upper bound.
- 'this' and
-
canonicalizeTypeArg
In reflection,Foo<?>.getUpperBounds()[0]is alwaysObject.class, even when Foo is defined asFoo<T extends String>. Thus directly calling<?>.is(String.class)will return false. To mitigate, we canonicalize wildcards by enforcing the following invariants:canonicalize(t)always produces the equal result for equivalent types. For example bothEnum<?>andEnum<? extends Enum<?>>canonicalize toEnum<? extends Enum<E>.canonicalize(t)produces a "literal" supertype of t. For example:Enum<? extends Enum<?>>canonicalizes toEnum<?>, which is a supertype (if we disregard the upper bound is implicitly an Enum too).- If
canonicalize(A) == canonicalize(B), thenFoo<A>.isSubtypeOf(Foo<B>)and vice versa. i.e.A.is(B)andB.is(A). canonicalize(canonicalize(A)) == canonicalize(A).
-
canonicalizeWildcardsInType
-
canonicalizeWildcardType
private static WildcardType canonicalizeWildcardType(TypeVariable<?> declaration, WildcardType type) -
canonicalizeWildcardsInParameterizedType
-
every
-
any
-
getRawTypes
-
isOwnedBySubtypeOf
-
getOwnerTypeIfPresent
Returns the owner type of aParameterizedTypeor enclosing class of aClass, or null otherwise. -
toGenericType
Returns the type token representing the generic type declaration ofcls. For example:TypeToken.getGenericType(Iterable.class)returnsIterable<T>.If
clsisn't parameterized and isn't a generic array, the type token of the class is returned. -
getCovariantTypeResolver
-
getInvariantTypeResolver
-
getSupertypeFromUpperBounds
-
getSubtypeFromLowerBounds
-
getArraySupertype
-
getArraySubtype
-
resolveTypeArgsForSubclass
-
newArrayClassOrGenericArrayType
Creates an array class ifcomponentTypeis a class, or else, aGenericArrayType. This is what Java7 does for generic array type parameters.
-