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

Lucas Jellema 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

One thought on “Using Java Reflection API to clean up code and speed up development

  1. 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

Comments are closed.

Next Post

An advanced Email component for the SOA suite

Facebook0TwitterLinkedinIn my previous post I described how to send an email with attachment from Oracle BPEL (https://technology.amis.nl/2012/02/05/sending-an-email-with-attachment-from-oracle-bpel/). This post described a rather simple approach to send emails. In this post I will describe an advanced email component as an alternative. In the ‘simple’ approach the used variables of the email […]