Listing 4: ClassInspector2.java — Lists all declarations of a class recursively

import java.lang.reflect.*;

class ClassInspector2
{
   static int level = 0;   // indentation depth
   static final String indentString = "   ";

   static void indent()
   {
      for (int i = 0; i < level; ++i)
         System.out.print(indentString);
   }

   static void indent(String s)
   {
      indent();
      System.out.print(s);
   }

   public static void inspect(Class c)
   {
      if (level == 0)
      {
         // Get Package
         Package pkg = c.getPackage();
         if (pkg != null)
            indent("package " + pkg.getName() + ";\n\n");
      }

      // Get Modifiers & Name
      String mods = Modifier.toString(c.getModifiers());
      indent();
      if (mods.length() > 0)
         System.out.print(mods + " ");
      if (!c.isArray() && !c.isInterface() && !c.isPrimitive())
         System.out.print("class ");
      System.out.println(c.getName());

      // Get Superclass
      Class sup = c.getSuperclass();
      if (sup != null)
      {
         ++level;
         indent("extends " + sup.getName() + "\n");
         --level;
      }

      // Get Interfaces
      Class[] interfaces = c.getInterfaces();
      if (interfaces.length > 0)
      {
         ++level;
         for (int i = 0; i < interfaces.length; ++i)
            indent("implements " + interfaces[i].getName() + "\n");
         --level;
      }

      // Start of class definition body
      indent("{\n");

      // Get Fields
      doFields(c);

      // Get Constructors
      doCtors(c);

      // Get Methods
      doMethods(c);

      // Get Nested classes (recursive)
      Class[] classes = c.getDeclaredClasses();
      if (classes.length > 0)
      {
         ++level;
         indent("// Nested Classes\n");
         for (int i = 0; i < classes.length; ++i)
            inspect(classes[i]);
         --level;
      }

      // End of class definition body
      indent("}\n");
   }

   static void doCtors(Class c)
   {
      Constructor[] ctors = c.getDeclaredConstructors();
      if (ctors.length == 0)
         return;

      ++level;
      indent("// Constructors\n");
      for (int i = 0; i < ctors.length; ++i)
      {
         Constructor ctor = ctors[i];
         String mods = Modifier.toString(ctor.getModifiers());
         indent();
         if (mods.length() > 0)
            System.out.print(mods + " ");
         System.out.print(ctor.getName() + "(");

         // Print parameters
         doParameters(ctor.getParameterTypes());
         
         System.out.println(");");
      }
      System.out.println();
      --level;
   }
   
   static void doFields(Class c)
   {
      Field[] fields = c.getDeclaredFields();
      if (fields.length == 0)
         return;

      ++level;
      indent("// Fields\n");
      for (int i = 0; i < fields.length; ++i)
      {
         Field fld = fields[i];
         String type = fld.getType().getName();
         String mods = Modifier.toString(fld.getModifiers());
         indent();
         if (mods.length() > 0)
            System.out.print(mods + " ");
         System.out.println(type + " " + fld.getName() +";");
      }
      System.out.println();
      --level;
   }

   static void doMethods(Class c)
   {
      Method[] methods = c.getDeclaredMethods();
      if (methods.length == 0)
         return;

      ++level;
      indent("// Methods\n");
      for (int i = 0; i < methods.length; ++i)
      {
         Method m = methods[i];
         Class retType = m.getReturnType();
         String mods = Modifier.toString(m.getModifiers());
         indent();
         if (mods.length() > 0)
             System.out.print(mods + " ");
         System.out.print(retType.getName() + " " +
                          m.getName() + "(");

         // Print parameters
         doParameters(m.getParameterTypes());
         
         System.out.println(");");
      }
      System.out.println();
      --level;
   }

   static void doParameters(Class[] parms)
   {
      int nParms = parms.length;
      for (int j = 0; j < nParms; ++j)
      {
         Class parmType = parms[j];
         if (j > 0)
            System.out.print(", ");
         System.out.print(parmType.getName());
      }
   }

   public static void main(String[] args)
      throws ClassNotFoundException
   {
      inspect(Class.forName("java.util.TreeMap"));
   }
}
— End of Listing —