Dump a class using Reflection : Class « Reflection « Java






Dump a class using Reflection

      
/*
 * ReflectClass.java -  Dump a class using Reflection.
 *
 * Copyright (c) 1997 Chuck McManis, All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies.
 *
 * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
 * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS
 * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
 * OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

import java.lang.reflect.*;
import java.util.*;

public class ReflectClass {

    static String tName(String nm, Hashtable ht) {
        String yy;
        String arr;

        if (nm.charAt(0) != '[') {
            int i = nm.lastIndexOf(".");
            if (i == -1)
                return nm; // It's a primitive type, ignore it.
            else {
                yy = nm.substring(i+1);
                if (ht != null)
                    ht.put(nm, yy); // note class types in the hashtable.
                return yy;
            }
        }
        arr = "[]";
        if (nm.charAt(1) == '[')
            yy = tName(nm.substring(1), ht);
        else {
            switch (nm.charAt(1)) {
                case 'L' :
                    yy = tName(nm.substring(nm.indexOf("L")+1, nm.indexOf(";")), ht);
                    break;
                case 'I':
                    yy = "int";
                    break;
                case 'V':
                    yy = "void";
                    break;
                case 'C':
                    yy = "char";
                    break;
                case 'D':
                    yy = "double";
                    break;
                case 'F':
                    yy = "float";
                    break;
                case 'J':
                    yy = "long";
                    break;
                case 'S':
                    yy = "short";
                    break;
                case 'Z':
                    yy = "boolean";
                    break;
                case 'B':
                    yy = "byte";
                    break;
                default:
                    yy = "BOGUS:"+nm;
                    break;

            }
        }
        return yy+arr;
    }

    public static void main(String args[]) {
        Constructor   cn[];
        Class         cc[];
        Method        mm[];
        Field         ff[];
        Class         c = null;
        Class         supClass;
        String      x, y, s1, s2, s3;
        Hashtable classRef = new Hashtable();

      if (args.length == 0) {
            System.out.println("Please specify a class name on the command line.");
            System.exit(1);
        }

        try {
            c = Class.forName(args[0]);
        } catch (ClassNotFoundException ee) {
            System.out.println("Couldn't find class '"+args[0]+"'");
            System.exit(1);
        }

        /*
         * Step 0: If our name contains dots we're in a package so put
         * that out first.
         */
        x = c.getName();
        if (x.lastIndexOf(".") != -1) {
            y = x.substring(0, x.lastIndexOf("."));
            System.out.println("package "+y+";\n\r");
        }

        /*
         * Let's use the Reflection API to sift through what is
         * inside this class.
         *
         * Step 1: Collect referenced classes
         * This step is used so that I can regenerate the import statements.
         * It isn't strictly required of course, Java works just fine with
         * fully qualified object class names, but it looks better when you
         * use 'String' rather than 'java.lang.String' as the return type.
         */

        ff = c.getDeclaredFields();
        for (int i = 0; i < ff.length; i++) {
            x = tName(ff[i].getType().getName(), classRef);
        }

        cn = c.getDeclaredConstructors();
        for (int i = 0; i < cn.length; i++) {
            Class cx[] = cn[i].getParameterTypes();
            if (cx.length > 0) {
                for (int j = 0; j < cx.length; j++) {
                    x = tName(cx[j].getName(), classRef);
                }
            }
        }

        mm = c.getDeclaredMethods();
        for (int i = 0; i < mm.length; i++) {
            x = tName(mm[i].getReturnType().getName(), classRef);
            Class cx[] = mm[i].getParameterTypes();
            if (cx.length > 0) {
                for (int j = 0; j < cx.length; j++) {
                    x = tName(cx[j].getName(), classRef);
                }
            }
        }

        // Don't import ourselves ...
        classRef.remove(c.getName());

        /*
         * Step 2: Start class description generation, start by printing
         *  out the import statements.
         *
         * This is the line that goes 'public SomeClass extends Foo {'
         */
        for (Enumeration e = classRef.keys(); e.hasMoreElements(); ) {
            System.out.println("import "+e.nextElement()+";");
        }
        System.out.println();

        /*
         * Step 3: Print the class or interface introducer. We use
         * a convienience method in Modifer to print the whole string.
         */
        int mod = c.getModifiers();
        System.out.print(Modifier.toString(mod));

        if (Modifier.isInterface(mod)) {
            System.out.print(" interface ");
        } else {
            System.out.print(" class ");
        }
        System.out.print(tName(c.getName(), null));

        supClass = c.getSuperclass();
        if (supClass != null) {
            System.out.print(" extends "+tName(supClass.getName(), classRef));
        }
        System.out.println(" {");

        /*
         * Step 4: Print out the fields (internal class members) that are declared
         * by this class.
         *
         * Fields are of the form [Modifiers] [Type] [Name] ;
         */

        System.out.println("\n\r/*\n\r * Field Definitions.\r\n */");
        for (int i = 0; i < ff.length; i++) {
            Class ctmp = ff[i].getType();
            int md     = ff[i].getModifiers();

            System.out.println("    "+Modifier.toString(md)+" "+
                    tName(ff[i].getType().getName(), null) +" "+
                    ff[i].getName()+";");
        }


        /*
         * Step 5: Print out the constructor declarations.
         *
         * We note the name of the class which is the 'name' for all
         * constructors. Also there is no type, so the definition is
         * simplye [Modifiers] ClassName ( [ Parameters ] ) { }
         *
         */
        System.out.println("\n\r/*\n\r * Declared Constructors. \n\r */");
        x = tName(c.getName(), null);
        for (int i = 0; i < cn.length; i++) {
            int md = cn[i].getModifiers();
            System.out.print("    " + Modifier.toString(md) + " " + x);

            Class cx[] = cn[i].getParameterTypes();
            System.out.print("( ");
            if (cx.length > 0) {
                for (int j = 0; j < cx.length; j++) {
                    System.out.print(tName(cx[j].getName(), null));
                    if (j < (cx.length - 1)) System.out.print(", ");
                }
            }
            System.out.print(") ");
            System.out.println("{ ... }");
        }

        /*
         * Step 6: Print out the method declarations.
         *
         * Now methods have a name, a return type, and an optional
         * set of parameters so they are :
         *  [modifiers] [type] [name] ( [optional parameters] ) { }
         */
        System.out.println("\n\r/*\n\r * Declared Methods.\n\r */");
        for (int i = 0; i < mm.length; i++) {
            int md = mm[i].getModifiers();
            System.out.print("    "+Modifier.toString(md)+" "+
                    tName(mm[i].getReturnType().getName(), null)+" "+
                    mm[i].getName());

            Class cx[] = mm[i].getParameterTypes();
            System.out.print("( ");
            if (cx.length > 0) {
                for (int j = 0; j < cx.length; j++) {
                    System.out.print(tName(cx[j].getName(), classRef));
                    if (j < (cx.length - 1)) System.out.print(", ");
                }
            }
            System.out.print(") ");
            System.out.println("{ ... }");
        }

        /*
         * Step 7: Print out the closing brace and we're done!
         */
        System.out.println("}");
    }
}

   
    
    
    
    
    
  








Related examples in the same category

1.Class Reflection: class modifierClass Reflection: class modifier
2.Class Reflection: class nameClass Reflection: class name
3.Class Reflection: name for super classClass Reflection: name for super class
4.Object Reflection: create new instance
5.Class reflectionClass reflection
6.This class shows using Reflection to get a field from another classThis class shows using Reflection to get a field from another class
7.Show the class keyword and getClass() method in actionShow the class keyword and getClass() method in action
8.Simple Demonstration of a ClassLoader WILL NOT COMPILE OUT OF THE BOX
9.Demonstrate classFor to create an instance of an object
10.CrossRef prints a cross-reference about all classes named in argv
11.Make up a compilable version of a given Sun or other API
12.Show a couple of things you can do with a Class object
13.Reflect1 shows the information about the class named in argv
14.Show that you can, in fact, take the class of a primitive
15.JavaP prints structural information about classes
16.Provides a set of static methods that extend the Java metaobject
17.Demonstration of speed of reflexive versus programmatic invocation
18.Use reflection to get console char set
19.Load the class source location from Class.getResource()
20.Access the enclosing class from an inner class
21.Use reflection to dynamically discover the capabilities of a class.
22.Get the class By way of a string
23.Get the class By way of .class
24.Return a String representation of an object's overall identity
25.Manipulate Java class files in strange and mysterious ways
26.Class file reader for obtaining the parameter names for declared methods in a class
27.Convert a given String into the appropriate Class.
28.Manipulate Java classes
29.Encapsulates a class serialVersionUID and codebase.
30.This program uses reflection to spy on objects
31.This program uses reflection to print all features of a classThis program uses reflection to print all features of a class
32.Get Unqualified Name
33.Return a paranthesis enclosed, comma sepearated String of all SimpleClass names in params.
34.Adds the class SimpleNames, comma sepearated and surrounded by paranthesis to the call StringBuffer
35.Class Finder