# Java Notes

# Class class

Like a human thinking about his/her own thinking, the process of a running program examining its classes is called reflection or introspection.

There is run-time information about classes that you can access. The central class representing this information is `java.lang.Class`, a class confusingly named `Class`.

## Use the Object `getClass()` method to get a Class object

Every class has the class `Object` as an ancestor. A reflection method in the Object class is `getClass()`, which returns the Class of that object.

## Class methods

`java.lang.Class` has two useful methods: `getName()` for getting a string name of the class and `getSuperclass()` for getting the Class object of the parent class, or null if this is the Object class. For example,

    String s = "abc";
    Class cls;
    cls = s.getClass();  // Represents the String class.
    System.out.println(cls.getName()); // Prints "java.lang.String"

## Example - What class is the content pane?

I wanted to know the type returned by the JFrame `getContentPane()` method. The documenation says it returns a `Container` object, but that only means that it returns `Container` or a subclass of `Container`. This program prints the inheritance hierarchy for any object. Change SIMPLE to false if you want to see the name with its package qualifications.

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
    // File   : oop/reflection/InheritanceLister.java
    // Purpose: Demo reflection using the Class class.
    // Author : Fred Swartz -- 2006-11-04
    // Enhancements: Perhaps output something that can be read by UMLGraph.
    // NOTE: simpleName() returns zero length name for anon classes!

    import java.awt.*;
    import javax.swing.*;
    import java.util.*;

    class InheritanceLister {
        //================================================================ constants
        private static final boolean SIMPLE = true;

        //============================================================== method main
        public static void main(String[] args) {
            JFrame f = new JFrame();
            Container c = f.getContentPane();
            System.out.println("\n---Content pane inheritance hierarchy");
            printAncestors(c);

            LayoutManager lm = c.getLayout();
            System.out.println("\n---Show default layout for content pane + ancestors.");
            printAncestors(lm);

            System.out.println("\n---Default JPanel layout inheritance hierarchy");
            printAncestors((new JPanel()).getLayout());
        }

        //==================================================== method printAncestors
        private static void printAncestors(Object obj) {
            for (Class cls : getAncestorList(obj)) {
                String name = SIMPLE ? cls.getSimpleName() : cls.getName();
                if (name.length() == 0) {
                    //... Must be an anonymous class.
                    name = "[Anonymous inner class]";
                }
                System.out.print("   " + name);

                //... Get array of interfaces that this class implements.
                boolean firstTime = true;
                for (Class inter : cls.getInterfaces()) {
                    if (firstTime) {
                        System.out.print(" implements ");
                        firstTime = false;
                    } else {
                        System.out.print(", ");
                    }
                    name = SIMPLE ? inter.getSimpleName() : inter.getName();
                    System.out.print(name);
                }
                System.out.println();
            }
        }

        //=================================================== method getAncestorList
        private static ArrayList<Class> getAncestorList(Object obj) {
            ArrayList<Class> result = new ArrayList<Class>();

            for (Class cls = obj.getClass(); cls != null; cls = cls.getSuperclass()) {
                result.add(cls);
            }

            Collections.reverse(result); // For normal top-down hierarchy.

            return result;
        }
    }

The output from this program is

    ---Content pane inheritance hierarchy
       Object
       Component implements ImageObserver, MenuContainer, Serializable
       Container
       JComponent implements Serializable, HasGetTransferHandler
       JPanel implements Accessible

    ---Show default layout for content pane + ancestors.
       Object
       BorderLayout implements LayoutManager2, Serializable
       [Anonymous inner class]

    ---Default JPanel layout inheritance hierarchy
       Object
       FlowLayout implements LayoutManager, Serializable

So the default content pane is a `JPanel`, and its layout is an anonymous subclass of `BorderLayout`. The default layout for a normal `JPanel` is just an ordinary `FlowLayout`.