THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

16.9. Generic Type Inspection


As you saw in Figure 16-1 on page 400, there are a number of interfaces to represent the different kinds of
types that can exist in your programs. So far we have focussed on Class objects and Member objects since
they are the more commonly used reflection objects, and we have only mentioned the other kinds of Type
objects in passing. This section looks at those other Type interfaces in more detail.


16.9.1. Type Variables


The GenericDeclaration interface, which is implemented by Class, Method, and Constructor,
has the single method getTypeParameters, which returns an array of TypeVariable objects. The
TypeVariable interface is itself a generic interface, declared as


interface TypeVariable


So, for example, the TypeVariable objects Method.getTypeParameters returns would be of type
TypeVariable.


Each type variable has a name returned by getName. It also has one or more upper bounds, obtained as a
Type[] from getBounds. Recall that if there is no explicit upper bound then the upper bound is Object.


The getGenericDeclaration method returns the Type object for the GenericDeclaration in
which the TypeVariable was declared. For example, the expression
TypeVariable.class.getTypeParameters()[0] would yield a TypeVariable object that
represents D in the declaration above. If you invoked getGenericDeclaration on this object, it would
return the Class object for the TypeVariable interface. More generally, for any
GenericDeclaration object g with at least one type parameter,


g.getTypeParameters()[i].getGenericDeclaration() == g


is always true (assuming i is a valid index of course).


Type variable objects are created on demand by the reflection methods that return them, and there is no
requirement that you receive the same TypeVariable object each time you ask for the same type variable.
However, the objects returned for a given type variable must be equivalent according to the equals method.
The bounds for a type variable are not created until getBounds is invoked, so getBounds can throw
TypeNotPresentException if a type used in the bounds cannot be found. It can also throw
MalformedParameterizedTypeException if any of the bounds refers to a ParameterizedType
instance that cannot be created for some reason.


16.9.2. Parameterized Types


Parameterized types, such as List, are represented by objects that implement the
ParameterizedType interface. You can obtain the actual type arguments for the parameterized type from
getActualTypeArguments, which returns an array of Type objects. For example,
getActualTypeArguments invoked on the parameterized type List would yield an array

Free download pdf