@Beta public abstract class TypeToken<T> extends TypeCapture<T> implements java.io.Serializable
Type
with generics.
Operations that are otherwise only available in Class
are implemented to support
Type
, for example isAssignableFrom(com.google.common.reflect.TypeToken<?>)
, isArray()
and getComponentType()
. It also provides additional utilities such as getTypes()
and resolveType(java.lang.reflect.Type)
etc.
There are three ways to get a TypeToken
instance:
Type
obtained via reflection. For example: TypeToken.of(method.getGenericReturnType())
.
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();
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.
Modifier and Type | Class and Description |
---|---|
private class |
TypeToken.ClassSet |
private class |
TypeToken.InterfaceSet |
private static class |
TypeToken.SimpleTypeToken<T> |
private static class |
TypeToken.TypeCollector<K>
Collects parent types from a sub type.
|
private static class |
TypeToken.TypeFilter |
class |
TypeToken.TypeSet
The set of interfaces and classes that
T is or is a subtype of. |
Modifier and Type | Field and Description |
---|---|
private java.lang.reflect.Type |
runtimeType |
private TypeResolver |
typeResolver
Resolver for resolving types with
runtimeType as context. |
Modifier | Constructor and 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) |
Modifier and Type | Method and Description |
---|---|
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)
|
boolean |
equals(java.lang.Object o)
Returns true if
o is another TypeToken that represents the same Type . |
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 ImmutableSet<java.lang.Class<? super T>> |
getImmediateRawTypes()
Returns the raw type of the class or parameterized type; if
T is type variable or
wildcard type, the raw types of all its upper bounds are returned. |
java.lang.Class<? super T> |
getRawType()
Returns the raw type of
T . |
(package private) static java.lang.Class<?> |
getRawType(java.lang.reflect.Type type) |
(package private) static ImmutableSet<java.lang.Class<?>> |
getRawTypes(java.lang.reflect.Type type) |
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() |
boolean |
isArray()
Returns true if this type is known to be an array type, such as
int[] , T[] ,
<? extends Map<String, Integer>[]> etc. |
private static boolean |
isAssignable(java.lang.reflect.Type from,
java.lang.reflect.Type to) |
private static boolean |
isAssignableBySubtypeBound(java.lang.reflect.Type from,
java.lang.reflect.WildcardType to) |
boolean |
isAssignableFrom(java.lang.reflect.Type type)
Check if this type is assignable from the given
type . |
boolean |
isAssignableFrom(TypeToken<?> type)
Returns true if this type is assignable from the given
type . |
private static boolean |
isAssignableFromAny(java.lang.reflect.Type[] fromTypes,
java.lang.reflect.Type to) |
private static boolean |
isAssignableFromGenericArrayType(java.lang.reflect.GenericArrayType from,
java.lang.reflect.Type to) |
private static boolean |
isAssignableToClass(java.lang.reflect.Type from,
java.lang.Class<?> to) |
private static boolean |
isAssignableToGenericArrayType(java.lang.reflect.Type from,
java.lang.reflect.GenericArrayType to) |
private static boolean |
isAssignableToParameterizedType(java.lang.reflect.Type from,
java.lang.reflect.ParameterizedType to) |
private static boolean |
isAssignableToWildcardType(java.lang.reflect.Type from,
java.lang.reflect.WildcardType to) |
boolean |
isPrimitive()
Returns true if this type is one of the nine primitive types (including
void ). |
private boolean |
isWrapper() |
private static boolean |
matchTypeArgument(java.lang.reflect.Type from,
java.lang.reflect.Type to) |
Invokable<T,java.lang.Object> |
method(java.lang.reflect.Method method)
|
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 static java.lang.reflect.Type |
subtypeBound(java.lang.reflect.Type type) |
private static java.lang.reflect.Type |
subtypeBound(java.lang.reflect.WildcardType type) |
private static java.lang.reflect.Type |
supertypeBound(java.lang.reflect.Type type) |
private static java.lang.reflect.Type |
supertypeBound(java.lang.reflect.WildcardType type) |
(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,
java.lang.Class<X> typeArg)
Returns a new
TypeToken where type variables represented by typeParam
are substituted by typeArg . |
<X> TypeToken<T> |
where(TypeParameter<X> typeParam,
TypeToken<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.
|
capture
private final java.lang.reflect.Type runtimeType
private transient TypeResolver typeResolver
runtimeType
as context.protected TypeToken()
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>>() {};
protected TypeToken(java.lang.Class<?> declaringClass)
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
private TypeToken(java.lang.reflect.Type type)
public static <T> TypeToken<T> of(java.lang.Class<T> type)
type
.public static TypeToken<?> of(java.lang.reflect.Type type)
type
.public final java.lang.Class<? super T> getRawType()
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:
T
is a Class
itself, T
itself is returned.
T
is a ParameterizedType
, the raw type of the parameterized type is
returned.
T
is a GenericArrayType
, the returned type is the corresponding array
class. For example: List<Integer>[] => List[]
.
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
.
private ImmutableSet<java.lang.Class<? super T>> getImmediateRawTypes()
T
is type variable or
wildcard type, the raw types of all its upper bounds are returned.public final java.lang.reflect.Type getType()
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);
}
X
- The parameter typetypeParam
- the parameter type variabletypeArg
- the actual type to substitutepublic 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);
}
X
- The parameter typetypeParam
- the parameter type variabletypeArg
- the actual type to substitutepublic 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
private java.lang.reflect.Type[] resolveInPlace(java.lang.reflect.Type[] types)
private TypeToken<?> resolveSupertype(java.lang.reflect.Type type)
@Nullable final TypeToken<? super T> getGenericSuperclass()
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.
@Nullable private TypeToken<? super T> boundAsSuperclass(java.lang.reflect.Type bound)
final ImmutableList<TypeToken<? super T>> getGenericInterfaces()
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.
private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(java.lang.reflect.Type[] bounds)
public final TypeToken.TypeSet getTypes()
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).
public final TypeToken<? super T> getSupertype(java.lang.Class<? super T> superclass)
superclass
. For example, if this is
ArrayList<String>
, Iterable<String>
is returned given the
input Iterable.class
.public final TypeToken<? extends T> getSubtype(java.lang.Class<?> subclass)
this
with subclass
as the raw class.
For example, if this is Iterable<String>
and subclass
is List
,
List<String>
is returned.public final boolean isAssignableFrom(TypeToken<?> type)
type
.public final boolean isAssignableFrom(java.lang.reflect.Type type)
type
.public final boolean isArray()
int[]
, T[]
,
<? extends Map<String, Integer>[]>
etc.public final boolean isPrimitive()
void
).public final TypeToken<T> wrap()
this
itself. Idempotent.private boolean isWrapper()
public final TypeToken<T> unwrap()
this
itself. Idempotent.@Nullable public final TypeToken<?> getComponentType()
int[]
, T[]
,
<? extends Map<String, Integer>[]>
etc.), or else null
is returned.public final Invokable<T,java.lang.Object> method(java.lang.reflect.Method method)
public final Invokable<T,T> constructor(java.lang.reflect.Constructor<?> constructor)
public boolean equals(@Nullable java.lang.Object o)
o
is another TypeToken
that represents the same Type
.equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object
public java.lang.String toString()
toString
in class java.lang.Object
protected java.lang.Object writeReplace()
final TypeToken<T> rejectTypeVariables()
TypeToInstanceMap
.private static boolean isAssignable(java.lang.reflect.Type from, java.lang.reflect.Type to)
private static boolean isAssignableFromAny(java.lang.reflect.Type[] fromTypes, java.lang.reflect.Type to)
private static boolean isAssignableToClass(java.lang.reflect.Type from, java.lang.Class<?> to)
private static boolean isAssignableToWildcardType(java.lang.reflect.Type from, java.lang.reflect.WildcardType to)
private static boolean isAssignableBySubtypeBound(java.lang.reflect.Type from, java.lang.reflect.WildcardType to)
private static boolean isAssignableToParameterizedType(java.lang.reflect.Type from, java.lang.reflect.ParameterizedType to)
private static boolean isAssignableToGenericArrayType(java.lang.reflect.Type from, java.lang.reflect.GenericArrayType to)
private static boolean isAssignableFromGenericArrayType(java.lang.reflect.GenericArrayType from, java.lang.reflect.Type to)
private static boolean matchTypeArgument(java.lang.reflect.Type from, java.lang.reflect.Type to)
private static java.lang.reflect.Type supertypeBound(java.lang.reflect.Type type)
private static java.lang.reflect.Type supertypeBound(java.lang.reflect.WildcardType type)
@Nullable private static java.lang.reflect.Type subtypeBound(java.lang.reflect.Type type)
@Nullable private static java.lang.reflect.Type subtypeBound(java.lang.reflect.WildcardType type)
static java.lang.Class<?> getRawType(java.lang.reflect.Type type)
static ImmutableSet<java.lang.Class<?>> getRawTypes(java.lang.reflect.Type type)
static <T> TypeToken<? extends T> toGenericType(java.lang.Class<T> cls)
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.
private TypeToken<? super T> getSupertypeFromUpperBounds(java.lang.Class<? super T> supertype, java.lang.reflect.Type[] upperBounds)
private TypeToken<? extends T> getSubtypeFromLowerBounds(java.lang.Class<?> subclass, java.lang.reflect.Type[] lowerBounds)
private TypeToken<? super T> getArraySupertype(java.lang.Class<? super T> supertype)
private java.lang.reflect.Type resolveTypeArgsForSubclass(java.lang.Class<?> subclass)
private static java.lang.reflect.Type newArrayClassOrGenericArrayType(java.lang.reflect.Type componentType)
componentType
is a class, or else, a
GenericArrayType
. This is what Java7 does for generic array type
parameters.