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.