Monday, April 16, 2012

How to invoke method by name in java dynamically using reflection

In Java you can invoke any method by its string name dynamically using reflection API. java.lang.reflect API provides powerful reflection mechanism which can load classes by its name even if classes are not available at compile time, Can get all methods including private and public from class and allow you to invoke any method dynamically using reflection. For those who are new in Java this sound pretty strange that at runtime you provide a method name using string and Java can run that method without any code for calling the method during compilation, but Reflection is such a powerful mechanism it allows to do lot of stuff dynamically and if you been using IDE like Netbeans or Eclipse , J2EE framework like Spring and Struts, these all used reflection to provide powerful configuration module and several other useful feature like code assist etc. Reflection is very comprehensive topic and there is a lot to learn but we will start with simple Java program example to invoke a method using reflection in  by providing name of method as String value.  

This Java article is continuation of my post on covering basic concepts like static and dynamic binding in Javawhen to use Interface in Java and why use PreparedStaement in Java. If you are new here or haven’t read them already then you may find them useful.


Java Program to invoke method by name dynamically using Reflection

Java program to invoke method by name in Java Reflection examplejava.lang.reflect package have a class called Method which represent method Reflectively and Method.invoke() is used to call any Java method dynamically using reflection. Method.invoke() takes an object whose method has to call and list of parameters to be passed to method and throws InvocationTargetException if called method throws any Exception. here is complete code example of calling method dynamically in Java using Reflection:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Simple Java program to invoke method by providing name as String.
 * Reflective calls are slower than normal call so calling method using reflection
 * should be use carefully.
 */

public class MethodInvocationReflection {

    public static void main(String args[]) {
       Class loadedList = null;
       List list = null;
       try {
            //loading class dynamically using reflection
            loadedList = Class.forName("java.util.ArrayList");
            list = (List) loadedList.newInstance();
         
            //calling method using interface on reflective instance
            list.add("abc");
            list.add("bcd");

        } catch (InstantiationException ex) {
            System.err.println("Not able to create Instance of Class");
        } catch (IllegalAccessException ex) {
            System.err.println("Not able to access Class");
        } catch (ClassNotFoundException ex) {
            System.err.println("Not able to find Class");
        }
   
       try {
            //getting method instance reflectively
            Method m = loadedList.getMethod("size", (Class[]) null);
         
            //calling method in java using reflection dynamically
            Object size = m.invoke(list, (Object[]) null);
            System.out.println("Result of dynamically invoking method in Java, Size: " + size);

        } catch (NoSuchMethodException ex) {
            System.err.println("Not able to find Method on class");
            ex.printStackTrace();
        } catch (SecurityException ex) {
            System.err.println("Security Exception raised");
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            System.err.println("Not able to access method ");
            ex.printStackTrace();
        } catch (IllegalArgumentException ex) {
            System.err.println("Incorrect supplied arguments");
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            System.err.println("Not able to invoke method by String in Java");
            ex.printStackTrace();
        }
    }
}

Important points while calling Java method using reflection:

Here are few points worth noting while invoking method by giving its name and using reflection, I agree that reflection provides flexibility but it also has some disadvantage :

1) Reflection in Java has serious performance issues and calling same method reflectively is more than 2 to 3 times slower than normal method call even in modern JVM, So use reflection only if its genuinely needed and there is no other way around.

2) Invoking method using reflection also has some disadvantage like compile time checking of method parameters, order of parameters and return type etc. Since we use method.invoke() to call methods we lose all compile time checks and any typo or error will only be reflected in run time wrapped under InvocationTargetException.

3) Another problem is too much code for invoking method or creating instance using reflection as you see we have written 20 line of code to invoke method which can be converted into just two lines if you call any method normally.

4) Last thing to note is using Interface object for calling method instead of using reflection or invoking method by name. if you see above Java program to invoked method by name,  we have used List interface type to refer object created using reflection and called method List.add() like normal method only List.size() is called reflectively. This is one of best practices while using reflection.

That's all on how to invoke method by name in Java dynamically using Reflection. Reflection is powerful but use it with caution. Call method with it’s interface even if Class is loaded dynamically using reflection, that is better than calling method by its string name using method.invoke().

Other Java Programming tutorials you may like:

7 comments :

Anonymous said...

If it's so powerful to turn private into public, why not re-introduce the even more powerful GOTO? Lets call it a design pattern :D

Javin @ programming questions said...

@Anonymous, changing private to public is not good practice, there are very few scenario when you want to use Reflection to change private field to public, like for testing purpose you can use reflection to make private method accessible.I agree that Reflection is very powerful in terms of flexibility it offer like you can create an object from xml configuration but it comes with cost of performance. Regarding GOTO , your guess is as good as mine :)

raja said...

Due this Reflection its possible to get all the information about a particular class

Pandit said...

Tip 4 "Use Interface to call method using reflection" is also explained in Effective Java book with good detail. I love that tip. no doubt reflection is powerful but as you said there should be guideline when to call method using reflection and when directly. My approach is to call method normally if information is available on compile time or call method by its name when method name is decided on run time.

Pushkar said...

@raja, yes you can get all information about a particular class using reflection like all declared field include public and private, all declared method including public and private, methods inherited from super class or super interface. I suggest looking on reflection API for complete details.

Sukhbeer said...

don't invoke java method using Reflection its very slow, Instead use Interface to call methods, even though object will be created by Reflection, calling method using Interfaces rather than java.lang.reflect Method would be much faster. Another disadvantage of invoking method dynamically is that its difficult to debug.

Oluwasayo Oladeji said...

@Raja if you're so concerned about the security of your program, you can prohibit reflections in production using security policies. You may want to look at http://stackoverflow.com/questions/770635/disable-java-reflection-for-the-current-thread

Post a Comment