// used in printType() for labeling type names
private static String[]
basic = { "class", "interface",
"enum", "annotation" },
supercl = { "extends", "implements" },
iFace = { null, "extends" };
private void printType(
Type type, int depth, String[] labels)
{
if (type == null) // stop recursion -- no supertype
return;
// turn the Type into a Class object
Class<?> cls = null;
if (type instanceof Class<?>)
cls = (Class<?>) type;
else if (type instanceof ParameterizedType)
cls = (Class<?>)
((ParameterizedType)type).getRawType();
else
throw new Error("Unexpected non-class type");
// print this type
for (int i = 0; i < depth; i++)
out.print(" ");
int kind = cls.isAnnotation()? 3 :
cls.isEnum()? 2 :
cls.isInterface()? 1 : 0;
out.print(labels[kind] + " ");
out.print(cls.getCanonicalName());
// print generic type parameters if present
TypeVariable<?>[] params = cls.getTypeParameters();
if (params.length > 0) {
out.print('<');
for (TypeVariable<?> param : params) {
out.print(param.getName());
out.print(", ");
}
out.println("\b\b>");
}
else
out.println();
// print out all interfaces this class implements
Type[] interfaces = cls.getGenericInterfaces();
for (Type iface : interfaces) {
printType(iface, depth + 1,
cls.isInterface()? iFace : supercl);
}
// recurse on the superclass
printType(cls.getGenericSuperclass(),
depth + 1, supercl);
}
}
This program loops through the names provided on the command line, obtains the Class object for each
named type and invokes printType on each of them. It must do this inside a TRy block in case there is no
class of the specified name. Here is its output when invoked on the utility class java.util.HashMap:
class java.util.HashMap<K, V>