Explain Codes LogoExplain Codes Logo

Invoking a static method using reflection

java
reflection
method-invocation
java-reflection-api
Nikita BarsukovbyNikita Barsukov·Nov 6, 2024
TLDR

To invoke a static method in Java by reflection use Class.forName() to get the class object and getMethod() for obtaining the method. Call invoke() with null as the object argument for static methods.

Method staticMethod = Class.forName("com.example.MyClass").getMethod("myStaticMethod", ParameterType.class); Object result = staticMethod.invoke(null, new ParameterType("arg"));

Always handle exceptions like ClassNotFoundException, NoSuchMethodException, and IllegalAccessException.

How to retrieve the method with precision

Retrieving a method correctly is a key step before you invoke it:

  • Use getMethod() when dealing with public static methods, and ensure you provide the exact parameter types in the method's signature.
getMethod("methodToInvoke", String.class) // 🦄 beware of unicorn parameters, ensure right type
  • Use getDeclaredMethod() for accessing private static methods. Evoke your inner power by calling setAccessible(true).
setAccessible(true); // 😎 taking off the invisible cloak
  • Class.forName() is your best friend when you know the class name but need to obtain the Class object on the fly.
Class.forName("com.example.MyClass") // like Gandalf, summoning MyClass from oblivion 🧙‍♂️
  • In reflection, everything goes for exact match. int.class is not interchangeable with Integer.class.

The arts of invoking a method

While invoking a method the reflective behavior differs from the traditional:

  • When using reflection, static method invocation is done via Method.invoke(null, args). The null replaces the object instance as there's no instance for static methods.
invoke(null, "Hello") // "Hello" is the magical word, not "null" 🪄
  • For static methods with zero arguments, you can omit the args array or pass new Object[0]. It's your choice.
invoke(null) // too silent to hear any argument 😶

Handling reflection exceptions like a pro

It won't always be a sunny day with reflection, be prepared for some exceptions:

  • IllegalAccessException: Thrown due to insufficient access rights, usually comes when trying to access a private method without setting it accessible.
  • InvocationTargetException: This is a wrapping exception, which contains any exception thrown by the invoked method itself.
  • IllegalArgumentException: Indicates that the method was applied an inappropriate argument.

Making reflection more practical

Use these practical points to ease your experience with reflection:

Iterating all methods

When your method name can vary, iterate over all methods and use filters according to your requirements. You can filter by name, return type, parameter types, or modifiers.

Alternatives to Java's native reflection

Although Java's native reflection API is quite powerful, you can opt for alternative reflection libraries like Groovy's ReflectionUtils. Assess the benefits and potential overheads before embracing them.

Beware of edge cases

Reflective calls can fail due to some common, yet easily overlooked edge cases: overloaded methods, difference between primitive and wrapper types, or disparities in classloaders. Be vigilant!

Maintaining code with reflection

While maintaining a codebase with reflection, take into account these following points:

Documentation

Properly document the sections where reflection is used as it is a complex process and might confuse other developers.

Unit Testing

Create numerous unit tests for methods using reflection to ensure they behave as expected, even with changes in the codebase.

Performance

Monitor the performance of your application as using reflection can slow down your application. Alternatives like MethodHandles can be considered if optimization is necessary.