Reflection in Java



General Information

Serialization

Reflection

Reflection here means introspection --- the ability of the program to examine itself.

At the top of the object hierary in Java is the unique class . All subclasses inherit the method . What type of value does . return? It returns the class . The class is an immutable structure that contains (meta) information about the class.

Where do objects come from?

  1. From .
          String str = "abc";
          Class c1 = str.getClass();
          

  2. From the method Class.getSuperclass()
          Button b = new Button();
          Class c1 = b.getClass();
          Class c2 = c1.getSuperclass();
          
    BTW getSuperclass() returns null for the class Object.

  3. From the static method Class.forName()
          Class c1 = Class.forName ("java.lang.String");
          Class c2 = Class.forName ("java.awt.Button");
          Class c3 = Class.forName ("Main$InnerClass");
          Class c4 = Class.forName ("I");
          Class c5 = Class.forName ("[I");
          

  4. From the .class syntax
          Class c1 = String.class;
          Class c2 = java.awt.Button.class;
          Class c3 = Main.InnerClass.class;
          Class c4 = int.class;
          Class c5 = int[].class;
          

  5. From the primitive wrapper classes
          Class c1 = Boolean.TYPE;
          Class c2 = Byte.TYPE;
          Class c3 = Character.TYPE;
          Class c4 = Short.TYPE;
          Class c5 = Integer.TYPE;
          Class c6 = Long.TYPE;
          Class c7 = Float.TYPE;
          Class c8 = Double.TYPE;
          Class c9 = Void.TYPE;
          

What can you do with a java.lang.Class object? You can get a resource associated with the class (which belongs to a different topic). A java.lang.Class object allows you to create new instances of the class.

(As permitted by the security manager) you can

Array are objects. Working with arrays. The java.lang.reflect.Array class (Java API documentation) (local copy).

JDI (Java Debug Interface)

JavaBeans

Purpose:
write self-contained, reusable software units that can be visually connected with other components.
JavaBean:
feature names adhere to specific design patterns in order to be exposed
Constituents:
properties, events, persistence
java.bean:
Reflection, customization
BDK
beanbox, property editors, demos
beanbox

SimpleBean

      public class SimpleBean extends Canvas
         implements Serializable{
      
         private Color color = Color.green;

	 //property getter method
	 public Color getColor(){
	    return color;
	 }

	 //property setter method. Sets new SimpleBean
	 //color and repaints.
	 public void setColor(Color newColor){
	    color = newColor;
	    repaint();
	 }

	 public void paint(Graphics g) {
	    g.setColor(color);
	    g.fillRect(20, 5, 20, 30);
	 }

         //Constructor sets inherited properties
         public SimpleBean(){
            setSize(60,40);
            setBackground(Color.red);
         }
      }
      

property

BeanInfo

Creating a BeanInfo Class

This section uses the ExplicitButtonBeanInfo demo class to illustrate creating a BeanInfo class. Here are the general steps to make a BeanInfo class:

  1. Name your BeanInfo class. You must append the string "BeanInfo" to the target class name. If the target class name is ExplicitButton, then its associated Bean information class must be named ExplicitButtonBeanInfo

  2. Subclass SimpleBeanInfo. This is a convenience class that implements BeanInfo methods to return null, or an equivalent no-op value.
    public class ExplicitButtonBeanInfo extends SimpleBeanInfo {
    
    Using SimpleBeanInfo saves you from implementing all the BeanInfo methods; you only have to override those methods you need.

  3. Override the appropriate methods to return the properties, methods, or events that you want exposed. ExplicitButtonBeanInfo overrides the getPropertyDescriptors() method to return four properties:
    public PropertyDescriptor[] getPropertyDescriptors() {
        try {  
            PropertyDescriptor background =
                new PropertyDescriptor("background", beanClass);
            PropertyDescriptor foreground =
                new PropertyDescriptor("foreground", beanClass);
            PropertyDescriptor font =
                new PropertyDescriptor("font", beanClass);
            PropertyDescriptor label =
                new PropertyDescriptor("label", beanClass);
     
            background.setBound(true);
            foreground.setBound(true);
            font.setBound(true);
            label.setBound(true);
             
            PropertyDescriptor rv[] =
                {background, foreground, font, label};
            return rv;
        } catch (IntrospectionException e) {
             throw new Error(e.toString());
        }
    }        
    
    There are two important things to note here:

  4. Optionally associate an icon with the target Bean.
    public java.awt.Image getIcon(int iconKind) {
        if (iconKind == BeanInfo.ICON_MONO_16x16 ||
            iconKind == BeanInfo.ICON_COLOR_16x16 )
        {
            java.awt.Image img = loadImage("ExplicitButtonIcon16.gif");
            return img;
        }
        if (iconKind == BeanInfo.ICON_MONO_32x32 ||
            iconKind == BeanInfo.ICON_COLOR_32x32 )
        {
            java.awt.Image img = loadImage("ExplicitButtonIcon32.gif");
            return img;
        }
        return null;
    }
    
    The BeanBox displays this icon next to the Bean name in the ToolBox. You can expect builder tools to do the same.

  5. Specify the target Bean class, and, if the Bean has a customizer, specify it also.
    public BeanDescriptor getBeanDescriptor() {
        return new BeanDescriptor(beanClass, customizerClass);
    }
    ...
    private final static Class beanClass = ExplicitButton.class;
    private final static Class customizerClass = OurButtonCustomizer.class;
    

Keep the BeanInfo class in the same directory as its target class. The BeanBox first searches for a target Bean's BeanInfo class in the target Bean's package path. If no BeanInfo is found, then the Bean information package search path (maintained by the Introspector) is searched. The default Bean information search path is sun.beans.infos. If no BeanInfo class is found, then low-level reflection is used to discover a Bean's features.


Ryan Stansifer <ryan@cs.fit.edu>
Last modified: Thu Apr 14 15:19:25 EDT 2005