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

Lucas Jellema 1
0 0
Read Time:1 Minute, 39 Second

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

About Post Author

Lucas Jellema

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director and Oracle Developer Champion. Solution architect and developer on diverse areas including SQL, JavaScript, Kubernetes & Docker, Machine Learning, Java, SOA and microservices, events in various shapes and forms and many other things. Author of the Oracle Press book Oracle SOA Suite 12c Handbook. Frequent presenter on user groups and community events and conferences such as JavaOne, Oracle Code, CodeOne, NLJUG JFall and Oracle OpenWorld.
Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %

Average Rating

5 Star
0%
4 Star
0%
3 Star
0%
2 Star
0%
1 Star
0%

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

In 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 […]
%d bloggers like this: