- Is it possible to invoke a method using a string as its name, without relying on the Reflection API?
- Call method by its name stored in string without reflection API?
- How to Invoke Method by Name in Java Dynamically Using Reflection? Example
- Java Program to invoke method by name dynamically using Reflection
- Important points while calling Java method using reflection:
Is it possible to invoke a method using a string as its name, without relying on the Reflection API?
The process involves locating the target method in a class, which is the most expensive operation. However, once the Method object is obtained, invoking the method on an object is a lightweight operation that is only slightly more expensive than direct method invocation. It is worth noting that the method parameter names can be obtained by compiling with debug, but the method argument names when invocation are still needed.
Call method by its name stored in string without reflection API?
By employing Reflection API, it is possible to invoke methods using their name saved as a string.
The Reflection API is not suitable for high performance applications as the methods are invoked at a very high rate in such applications, making it unsuitable for use in my application.
What other options exist in place of the Reflection API?
After conducting some investigation, I discovered that code generation libraries such as cglib are available for use.
However, I was unable to locate an instance where a method can be called using a string that contains its name.
It would be helpful to have a sample along with the alternative for reflection.
An update has been made regarding the implementation of a Master-Slave communication API. The plan is for slaves to remotely call master methods, with an estimated rate of approximately 50 method invocations per second for method invocation. Due to the continuous polling of slaves for a response by the master, it is being considered if reflection should be utilized at this high rate of invocation.
Give reflection a chance before dismissing it, and test whether it causes any performance issues on a recent JVM. It’s possible that you won’t encounter any problems.
Apart from cglib (which may not be suitable for your needs; refer to another answer for more information), your only viable alternative is to create a method that accepts a method name as input and invokes that method using a dispatch table or a similar mechanism. For instance:
public Object callMethod(String methodName, Object[] args) < switch (methodName) < // Using strings in `switch` requires a recent version of Java case "foo": return this.foo(args[0]); case "bar": this.bar(args[0], args[1]); return null; // . and so on. default: throw new AppropriateException(); >>
Within Cglib, there exists a class named FastMethod which serves the purpose of invoking a method using a non-reflective interface. To achieve this, the FastMethod class implements an interface and generates byte code to invoke the desired method. This approach bypasses the need for a costly reflective invocation.
Despite offering explicit support for method invocation via reflection, it is generally not recommended to use the Cglib class due to its outdated nature. Cglib was developed during a time when reflection was more expensive than it is today, but modern JVMs have since introduced a concept known as «inflation». Essentially, after the 15th reflective call, the JVM will automatically generate byte code for method invocation, rendering the explicit support offered by Cglib unnecessary.
The costliest operation is the lookup, not the reflective call. Naming the method to represent FastMethod is still necessary, even when using cglib, hence avoiding these costs is not possible.
My suggestion is to utilize reflection until you confirm that it is causing a performance bottleneck. It would be wise to employ a tool like JMH to support such an implementation. Additionally, it is important to keep in mind that classes consuming perm space can create issues for your users.
The notion that Reflection is sluggish is widely misunderstood. This was the case during the era of Java 1.3 or thereabouts.
In present times, Java Reflection has been optimized efficiently by utilizing dynamic bytecode generation. Additionally, the JVM has the ability to directly inline these calls into the caller, resulting in Reflection method invocations that are almost as quick as direct calls.
Some previous suggestions propose the utilization of cglib’s FastMethod. However, it has been demonstrated that its speed improvement is not substantial when compared to Reflection. To demonstrate this, a benchmark has been developed using the popular JMH framework.
@State(Scope.Benchmark) public class MethodInvoke < Method method; FastMethod fastMethod; @Setup public void init() throws NoSuchMethodException < method = getClass().getMethod("foo", int.class, long.class); method.setAccessible(true); fastMethod = FastClass.create(getClass()).getMethod("foo", new Class[] < int.class, long.class >); > @GenerateMicroBenchmark public long fastMethod() throws Exception < return (Long) fastMethod.invoke(this, new Object[] ); > @GenerateMicroBenchmark public long reflection() throws Exception < return (Long) method.invoke(this, 2, 3L); >public long foo(int a, long b) < return a + b; >>
Results on Java 7u51 (64-bit):
Benchmark Mode Samples Mean Mean error Units b.MethodInvoke.fastMethod thrpt 5 79248,583 3978,941 ops/ms b.MethodInvoke.reflection thrpt 5 76975,414 2844,730 ops/ms
FastMethod, unlike Reflection, lacks proper argument verification, etc. Despite being only 3% faster than msdt_code2, it is still preferred.
Generally, when performing introspective invocation on a method, it involves a two-step process. The initial step is to find the method that you want to invoke, and the second step is to invoke the method on a particular instance while passing the required parameters.
The costliest step in this procedure involves finding the target method within a class, as shown in Method method = TargetClass.getMethod(Class[] signature . ) . However, once the Method object is obtained, calling the method on an object, as demonstrated in method.invoke(targetObj, param. ) , is only slightly more expensive than invoking the method directly.
To exemplify this, I conducted a hasty comparison of the three techniques and obtained the ensuing outcomes (it is crucial to evaluate them in relation to one another):
- The invocation of Reflect method takes 167ms each time.
- The invocation of cache methods from the class took 36 ms.
- Direct invocation: 17ms
Keep in mind that the cost of introspection is fixed, therefore, the greater the amount of computation the method performs, the more similar these values will be.
In past projects, I have employed a method-caching technique to prioritize performance. In reality, it has been noted that the cost of introspection becomes insignificant when compared to the actual execution time of the method, as per Amdahl’s law.
A code for testing purposes that is designed to be quick and rough.
import java.lang.reflect.Method; import java.util.Random; /** * Created by maasg on 5/10/14. */ public class Instrospection < public static void main(String [] params) throws Exception < Random ran = new Random(); String[] methods = new String[] ; Target target = new Target(); // Warmup for (int i=0; i StringBuilder builder = new StringBuilder(); long t0 = System.currentTimeMillis(); for (int i=0; i System.out.println("Elapsed 1: "+(System.currentTimeMillis()-t0)); Method[] invokeMethods = new Method[] < Target.class.getMethod(methods[0], String.class), Target.class.getMethod(methods[1], String.class), Target.class.getMethod(methods[2], String.class), >; builder = new StringBuilder(); long t1 = System.currentTimeMillis(); for (int i=0; i System.out.println("Elapsed 2: "+(System.currentTimeMillis()-t1)); builder = new StringBuilder(); long t2 = System.currentTimeMillis(); for (int i=0; i builder.append(result.toString()); > System.out.println("Elapsed 3: "+(System.currentTimeMillis()-t2)); > >
How to invoke methods of a class (in java) when class, Sorted by: 1 You need to make sure the compiled class is in the webapp’s classpath (ie, WEB-INF/classes) and use the FQN (ie, add the package name). You could also make a JAR file of your …
How to Invoke Method by Name in Java Dynamically Using Reflection? Example
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 to 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 a lot of stuff dynamically and if you been using IDE like Netbeans or Eclipse, a J2EE framework like Spring and Struts , these all used reflection to provide powerful configuration module and several other useful features 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 Java, when 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.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 an interface on a 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 a 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() .