Here's a utility class that will dump information about a bean's exposed properties:

import java.beans.*;
import java.io.*;
import java.util.*;

public class SimpleBeanDumper {

    public static void dump(Class beanClass) throws IntrospectionException {
        dump(beanClass, new PrintWriter(System.out, true));
    }

    public static void dump(Class beanClass, PrintWriter out) throws IntrospectionException {
        if (beanClass == null) {
            throw new NullPointerException("No bean class specified");
        }
        if (out == null) {
            out = new PrintWriter(System.out, true);
        }

        out.println("Dumping Properties for: " + beanClass.getName());
        out.println();

        BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0, n = descriptors.length; i < n; i++) {
            PropertyDescriptor descriptor = descriptors[i];
            String propName = descriptor.getName();
            out.println(propName);
            out.println("  propertyType:        " + descriptor.getPropertyType());
            out.println("  readMethod:          " + descriptor.getReadMethod());
            out.println("  writeMethod:         " + descriptor.getWriteMethod());
            if (descriptor instanceof IndexedPropertyDescriptor) {
                IndexedPropertyDescriptor indexedDescriptor = (IndexedPropertyDescriptor)descriptor;
                out.println("  indexedPropertyType: " + indexedDescriptor.getIndexedPropertyType());
                out.println("  indexedReadMethod:   " + indexedDescriptor.getIndexedReadMethod());
                out.println("  indexedWriteMethod:  " + indexedDescriptor.getIndexedWriteMethod());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Class clazz = MyBean.class;
        if (args.length > 0) {
            clazz = Class.forName(args[0]);
        }
        dump(clazz);
    }

    public static class MyBean implements Serializable {
        public int getID() { return 0; }
        public void setID(int id) {}

        public String getId() { return null; }
        public void setId(String id) {}

        public String[] getFriends() { return null; }
        public String getFriends(int i) { return null; }
        public void setFriends(String[] friends) {}
        public void setFriends(int i, String friend) {}

        public Map getMap() { return null; }
        public void setMap(Map map) {}
    }
}

If the class is run as:

java SimpleBeanDumper

Then the output should look something like:

Dumping Properties for: SimpleBeanDumper$MyBean

ID
  propertyType:        int
  readMethod:          public int SimpleBeanDumper$MyBean.getID()
  writeMethod:         public void SimpleBeanDumper$MyBean.setID(int)
class
  propertyType:        class java.lang.Class
  readMethod:          public final native java.lang.Class java.lang.Object.getClass()
  writeMethod:         null
friends
  propertyType:        class [Ljava.lang.String;
  readMethod:          public java.lang.String[] SimpleBeanDumper$MyBean.getFriends()
  writeMethod:         public void SimpleBeanDumper$MyBean.setFriends(java.lang.String[])
  indexedPropertyType: class java.lang.String
  indexedReadMethod:   public java.lang.String SimpleBeanDumper$MyBean.getFriends(int)
  indexedWriteMethod:  public void SimpleBeanDumper$MyBean.setFriends(int,java.lang.String)
id
  propertyType:        class java.lang.String
  readMethod:          public java.lang.String SimpleBeanDumper$MyBean.getId()
  writeMethod:         public void SimpleBeanDumper$MyBean.setId(java.lang.String)
map
  propertyType:        interface java.util.Map
  readMethod:          public java.util.Map SimpleBeanDumper$MyBean.getMap()
  writeMethod:         public void SimpleBeanDumper$MyBean.setMap(java.util.Map)

In other words, a SimpleBeanDumper.MyBean instance exposes five properties: ID, class, friends, id, and map. Note that while most of the properties can be both read and written, the class property is read-only. Also note that the class property is actually inherited from java.lang.Object.

Here's another dump example, this time using java.util.HashMap:

java SimpleBeanDumper java.util.HashMap

The output should look something like:

Dumping Properties for: java.util.HashMap

class
  propertyType:        class java.lang.Class
  readMethod:          public final native java.lang.Class java.lang.Object.getClass()
  writeMethod:         null
empty
  propertyType:        boolean
  readMethod:          public boolean java.util.AbstractMap.isEmpty()
  writeMethod:         null

In other words, a HashMap instance exposes two simple read-only properties called class and empty.

  • No labels