APIdia Launch Partner
Top Description Fields Constructors Methods
com.sun.beans

public final Class TypeResolver

extends Object
Class Inheritance
Imports
java.lang.reflect.Array, .GenericArrayType, .ParameterizedType, .Type, .TypeVariable, .WildcardType, java.util.HashMap, .Map, sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl, .ParameterizedTypeImpl

This is utility class to resolve types.
Authors
Eamonn McManus, Sergey Malenkov
Since
1.7

Field Summary

Modifier and TypeField and Description
private static final WeakCache<Type, Map<Type, Type>>

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public static Class<?>

Returns:

a corresponding class
erase
(Type
the array of types to convert
type
)

Converts the given type to the corresponding class.

public static Class<?>[]

Returns:

an array of corresponding classes
erase
(Type[]
the array of types to convert
types
)

Converts all types in the given array to the corresponding classes.

private static Type

Returns:

a corresponding type for the generic array type, or the same type as type
fixGenericArray
(Type
the type to fix
type
)

Replaces a GenericArrayType with plain array class where it is possible.

private static Type

Returns:

a parameterized type for the class, or the same class as inClass
getActualType
(Class<?>
the base class used to resolve
inClass
)

Replaces a Class with type parameters with a ParameterizedType where every parameter is bound to itself.

private static void
prepare(Map<Type, Type>
the mappings of all type variables
map
,
Type
the next type in the hierarchy
type
)

Fills the map from type parameters to types as seen by the given type.

public static Type

Returns:

a resolved type
resolve
(Type
the type that supplies bindings for type variables
actual
,
Type
the type where occurrences of the variables in actual will be replaced by the corresponding bound values
formal
)

Replaces type variables of the given formal type with the types they stand for in the given actual type.

public static Type[]

Returns:

an array of resolved types
resolve
(Type
the type that supplies bindings for type variables
actual
,
Type[]
the array of types to resolve
formals
)

Replaces type variables of all formal types in the given array with the types they stand for in the given actual type.

public static Type

Returns:

a resolved type
resolveInClass
(Class<?>
the base class used to resolve
inClass
,
Type
the type to resolve
type
)

Replaces the given type in an inherited method with the actual type it has in the given inClass.

public static Type[]

Returns:

an array of resolved types
resolveInClass
(Class<?>
the base class used to resolve
inClass
,
Type[]
the array of types to resolve
types
)

Replaces all types in the given array with the actual types they have in the given inClass.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

CACHEback to summary
private static final WeakCache<Type, Map<Type, Type>> CACHE

Constructor Detail

TypeResolverback to summary
public TypeResolver()

Method Detail

eraseback to summary
public static Class<?> erase(Type type)

Converts the given type to the corresponding class. This method implements the concept of type erasure, that is described in section 4.6 of The Java Language Specification.

Parameters
type:Type

the array of types to convert

Returns:Class<?>

a corresponding class

eraseback to summary
public static Class<?>[] erase(Type[] types)

Converts all types in the given array to the corresponding classes.

Parameters
types:Type[]

the array of types to convert

Returns:Class<?>[]

an array of corresponding classes

See Also
erase(Type)
fixGenericArrayback to summary
private static Type fixGenericArray(Type type)

Replaces a GenericArrayType with plain array class where it is possible. Bug 5041784 is that arrays of non-generic type sometimes show up as GenericArrayType when using reflection. For example, a String[] might show up as a GenericArrayType where getGenericComponentType is String.class. This violates the specification, which says that GenericArrayType is used when the component type is a type variable or parameterized type. We fit the specification here.

Parameters
type:Type

the type to fix

Returns:Type

a corresponding type for the generic array type, or the same type as type

getActualTypeback to summary
private static Type getActualType(Class<?> inClass)

Replaces a Class with type parameters with a ParameterizedType where every parameter is bound to itself. When calling resolveInClass in the context of inClass, we can't just pass inClass as the actual parameter, because if inClass has type parameters that would be interpreted as accessing the raw type, so we would get unwanted erasure. This is why we bind each parameter to itself. If inClass does have type parameters and has methods where those parameters appear in the return type or argument types, we will correctly leave those types alone.

Parameters
inClass:Class<?>

the base class used to resolve

Returns:Type

a parameterized type for the class, or the same class as inClass

prepareback to summary
private static void prepare(Map<Type, Type> map, Type type)

Fills the map from type parameters to types as seen by the given type. The method is recursive because the type inherits mappings from its parent classes and interfaces. The type can be either a Class or a ParameterizedType. If it is a Class, it is either equivalent to a ParameterizedType with no parameters, or it represents the erasure of a ParameterizedType.

Parameters
map:Map<Type, Type>

the mappings of all type variables

type:Type

the next type in the hierarchy

resolveback to summary
public static Type resolve(Type actual, Type formal)

Replaces type variables of the given formal type with the types they stand for in the given actual type.

A ParameterizedType is a class with type parameters, and the values of those parameters. For example, Map<K,V> is a generic class, and a corresponding ParameterizedType might look like Map<K=String,V=Integer>. Given such a ParameterizedType, this method will replace K with String, or List<K> with List<String>, or List<? super K> with List<? super String>.

The actual argument to this method can also be a Class. In this case, either it is equivalent to a ParameterizedType with no parameters (for example, Integer.class), or it is equivalent to a "raw" ParameterizedType (for example, Map.class). In the latter case, every type parameter declared or inherited by the class is replaced by its "erasure". For a type parameter declared as <T>, the erasure is Object. For a type parameter declared as <T extends Number>, the erasure is Number.

Although type parameters are not inherited by subclasses in the Java language, they are effectively inherited when using reflection. For example, if you declare an interface like this...

public interface StringToIntMap extends Map<String,Integer> {}

...then StringToIntMap.class.getMethods() will show that it has methods like put(K,V) even though StringToIntMap has no type parameters. The K and V variables are the ones declared by Map, so TypeVariable#getGenericDeclaration() will return Map.class.

For this reason, this method replaces inherited type parameters too. Therefore if this method is called with actual being StringToIntMap.class and formal being the K from Map, it will return String.class.

In the case where actual is a "raw" ParameterizedType, the inherited type parameters will also be replaced by their erasures. The erasure of a Class is the Class itself, so a "raw" subinterface of StringToIntMap will still show the K from Map as String.class. But in a case like this...

public interface StringToIntListMap extends Map<String,List<Integer>> {}
public interface RawStringToIntListMap extends StringToIntListMap {}

...the V inherited from Map will show up as List<Integer> in StringToIntListMap, but as plain List in RawStringToIntListMap.

Parameters
actual:Type

the type that supplies bindings for type variables

formal:Type

the type where occurrences of the variables in actual will be replaced by the corresponding bound values

Returns:Type

a resolved type

resolveback to summary
public static Type[] resolve(Type actual, Type[] formals)

Replaces type variables of all formal types in the given array with the types they stand for in the given actual type.

Parameters
actual:Type

the type that supplies bindings for type variables

formals:Type[]

the array of types to resolve

Returns:Type[]

an array of resolved types

resolveInClassback to summary
public static Type resolveInClass(Class<?> inClass, Type type)

Replaces the given type in an inherited method with the actual type it has in the given inClass.

Although type parameters are not inherited by subclasses in the Java language, they are effectively inherited when using reflection. For example, if you declare an interface like this...

public interface StringToIntMap extends Map<String,Integer> {}

...then StringToIntMap.class.getMethods() will show that it has methods like put(K,V) even though StringToIntMap has no type parameters. The K and V variables are the ones declared by Map, so TypeVariable#getGenericDeclaration() will return Map.class.

The purpose of this method is to take a Type from a possibly-inherited method and replace it with the correct Type for the inheriting class. So given parameters of K and StringToIntMap.class in the above example, this method will return String.

Parameters
inClass:Class<?>

the base class used to resolve

type:Type

the type to resolve

Returns:Type

a resolved type

See Also
getActualType(Class), resolve(Type, Type)
resolveInClassback to summary
public static Type[] resolveInClass(Class<?> inClass, Type[] types)

Replaces all types in the given array with the actual types they have in the given inClass.

Parameters
inClass:Class<?>

the base class used to resolve

types:Type[]

the array of types to resolve

Returns:Type[]

an array of resolved types

See Also
getActualType(Class), resolve(Type, Type[])