THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

implements java.util.Map<K, V>
implements java.lang.Cloneable
implements java.io.Serializable
extends java.util.AbstractMap<K, V>
implements java.util.Map<K, V>
extends java.lang.Object


After the main method is the declaration of the output stream to use, by default System.out. The String
arrays are described shortly.


The printType method prints its own type parameter's description and then invokes itself recursively to
print the description of type's supertypes. Because we initially have general Type objects, we first have to
convert them to Class objects. The depth parameter keeps track of how far up the type hierarchy it has
climbed, indenting each description line according to its depth. The depth is incremented at each recursion
level. The labels array specifies how to label the classlabels[0] is the label if the type is a class;
labels[1] is for interfaces; labels[2] for enums; and labels[3] for annotation types. Note the order
in which we check what kind of type we havean enum type is a class, and an annotation type is an interface,
so we have to check for these more specific kinds of type first.


Three arrays are defined for these labels: basic is used at the top level, supercl is used for superclasses,
and iFace is used for superinterfaces of interfaces, which extend, not implement, each other. After we print
the right prefix, we use getCanonicalName to print the full name of the type. The Class class provides a
toString method, but it already adds "class" or "interface" in front. We want to control the prefix, so we
must create our own implementation. We look more at class names a little later.


Next, the type is examined to see if it is a generic type. All classes implement GenericDeclaration,
which defines the single method getTypeParameters that returns an array of TypeVariable objects.
If we have one or more type parameters then we print each of their names between angle brackets, just as they
would appear in your source code.


After printing the type description, printType invokes itself recursively, first on all the interfaces that the
original type implements and then on the superclass this type extends (if any), passing the appropriate label
array to each. Eventually, it reaches the Class object for Object, which implements no interfaces and
whose getGenericSuperclass method returns null, and the recursion ends.


Some simple query methods, a few of which you saw in the example, examine the kind of Class object that
you are dealing with:


public booleanisEnum()

Returns true if this Class object represents an enum.

public booleanisInterface()

Returns true if this Class object represents an interface (which includes
annotation types).

public booleanisAnnotation()

Returns true if this Class object represents an annotation type.

public booleanisArray()

Returns TRue if this Class object represents an array.
Free download pdf