import java.lang.reflect.Field;                 //needed for the get() method

/**
 * Use java reflection using objects of the "Class" class
 *
 * The JVM creates an object of the internal class "Class" for every class
 * that is loaded and run by the JVM.
 *
 * The object will contains lots of information about our class. 
 *
 */

public class Reflect
{
    static int count =  3;                      //define a static var (not used)
    char singleCharacter = 'y';                 //define a char var   (not used)
    String z;                                   //define a string     (not used)

    public static void main(String[ ] args)
    {   

        Reflect pgm = new Reflect();            //instantiate a Reflect object
                                                //which is really this program.
                                                //since no constructor is defined, 
                                                //use Java default constructor
        
        String text = "this is some text";

        if (text instanceof String)
            System.out.println("object text  is an instance of class 'String'");
        if (text instanceof Object)
            System.out.println("object text  is an instance of class 'Object'");

        if (pgm instanceof Reflect)
            System.out.println("this program is an instance of class 'Reflect'");

        System.out.println();

        Class ref   = pgm.getClass();           //get a reference to the JVM object
        String name = ref.getName();            //from there, getName() of class

        System.out.println("the name of the class is: " + name + "\n");

        pgm.output();                           //call the output method;
    }
    

   /****************************************************************************
    * Constructor
    ****************************************************************************/

//  Reflect( ) {                        //You don't need this since 
//  }                                   //Java offers an empty constructor

   /****************************************************************************
    * method: output
    ****************************************************************************/

    void output() 
    {
        /************************************************************************
         * Get a reference to the JVM class object that represent this program
         * once you have a reference to it, get information like name, etc.
         *
         ************************************************************************/

        Class ref   = this.getClass();          //get a reference to the JVM object
                                                //that represent this class
        
        String name = ref.getName();            //from there, getName() of class

        System.out.println("the name of the class is: " + name);
        System.out.println(ref + "\n");                           //the toString()

        /************************************************************************
         * Another way to do just the same thing
         * except here we get the reference through the .class
         *
         ***********************************************************************/

        Class ref2   = Reflect.class;

        String name2 = ref2.getName();

        System.out.println("the name of the class is: " + name2);
        System.out.println(ref2 + "\n");                          //the toString()

        /***********************************************************************
         * Get a reference to the superclass of this class 
         *
         **********************************************************************/

        Class superior = ref.getSuperclass();

        System.out.println("the name of the superclass is: " + superior.getName());
        System.out.println(superior + "\n");

        /***********************************************************************
         * Get a reference to the package of this class
         *
         **********************************************************************/

        Package pkg    = ref.getPackage();

        System.out.println("the name of the package is: " + pkg + "\n");

        /***********************************************************************
         * Print all the fields and methods 
         *
         **********************************************************************/

        Field[ ] fld = ref.getDeclaredFields();

        for (int i = 0; i < fld.length; i++)
        {               
            System.out.print(fld[i] + "\t");            

            fld[i].setAccessible(true);                 //allow me to access even if private

            try {
                String fldName  = fld[i].getName();     //get the name
                System.out.print(fldName + "=");
                Object fldValue = fld[i].get(this);     //get the value
                System.out.println(fldValue);           //method in the class Field
            }
            catch (IllegalAccessException e) { } 
        }
        System.out.println();

        /***********************************************************************
         * Print all the fields and methods 
         *
         **********************************************************************/

        Object[ ] mthd = ref.getDeclaredMethods();

        for (int i = 0; i < mthd.length; i++)   
            System.out.println(mthd[i]);                  
    }
}