Using Java Reflection API to clean up code and speed up development

1

The challenge was a simple one: my method is passed in an object. This object may or may not have a certain method – called getClientListeners(). When it does, the method should be invoked and the result from the call must be returned by my method. If the object does not expose such a getClientListeners() method, my method should return null.

Sounds simple enough. However because the objects do not implement a common interface that specifies the method getClientListeners(), I found myself writing repeated if-clauses, for all the known Class that could be passed in to my method:


if (uiComponent instanceof RichInputText) {
  RichInputText uixComponent = (RichInputText)uiComponent;
  cls = uixComponent.getClientListeners();
  if (cls == null) {
    cls = new ClientListenerSet();
    uixComponent.setClientListeners(cls);
  }
}

And that for a seriously large number of classes.

Then it hit me:

using the Reflection API I can still invoke a method generically on any object – without having to rely on the objects implementing some interface. With a little generic code leveraging Java Reflection, I could quickly cut many dozens of lines of code from my application. Besides, the application caters for any class that exposes the getClientListeners() method!

The new generic implementation of the code above looks like this

        ClientListenerSet cls = null;
        // use reflection to invoke the getClientListeners method if it exists on this uiComponent
        Method[] allMethods = uiComponent.getClass().getDeclaredMethods();
        for (Method m : allMethods) {
            String mname = m.getName();
            if (mname.startsWith("getClientListeners")) {
                try {
                    m.setAccessible(true);
                    Object o = m.invoke(uiComponent);
                    if (o instanceof ClientListenerSet) {
                        cls = (ClientListenerSet)o;
                        return cls;
                    }
                    // Handle any exceptions thrown by method to be invoked.
                } catch (InvocationTargetException x) {
                    Throwable cause = x.getCause();

                } catch (IllegalAccessException e) {
                }
            }
        }
        if (cls == null) {
            cls = new ClientListenerSet();
            for (Method m : allMethods) {
                String mname = m.getName();
                if (mname.startsWith("setClientListeners")) {
                    try {
                        Object o = m.invoke(uiComponent, cls);
                        // Handle any exceptions thrown by method to be invoked.
                    } catch (InvocationTargetException x) {
                        Throwable cause = x.getCause();

                    } catch (IllegalAccessException e) {
                    }
                }
            }
        }

Resources

Tutorial on the Java Reflection API: Invoking Methods

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

1 Comment

  1. Saurabh S. Pawse on

    Hi,
    A much simpler way is to call Class.getMethod() directly to get the Method instance:
    Method m = uiComponent.getClass().getMethod(“getClientListeners”,null);
    m.invoke(uiComponent);

    This way the loop can be avoided.

    Regards,
    Saurabh

Leave a Reply