Search this site


 Java tutorials home  Reflection introduction  Calling a method via reflection

Search this site:
Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java

 What do you think of this article? Did it help you? Found a mistake? Feedback and suggestions here

Calling a method via reflection in Java: details

On the previous page, we introduced the Java reflection API and showed a simple example of calling the String.length() method on a given string via reflection. On this page, we follow that example up with some further observations and common variations.

Class lookup

In this case, we looked up the class "manually" via Class.forName(). However, if the class name is fixed and resolvable at compile time, as it might well be in various typical cases, the compiler actually allows us to write the following shorthand:

Method lenMethod = String.class.getDeclaredMethod(...);

Method parameters

A method is defined not only by its name, but also by the list of parameters it can take. As you're probably aware, Java permits polymorphism: that is, various methods can exist on the same class provided that they have different parameter lists. Therefore, when we retrieve a Method object, we must supply not just the name, but also a list of parameter types. The list of paramter types is supplied as an array of Class objects, although in the case of a method like String.length() that takes no parameters, the array is empty.

When we do have to supply a Class object representing a parameter type, using the above compiler shortcut for looking up the Class object can be useful. For example, we could retrieve String.endsWith() method (which takes a single String parameter) as follows:

String.class.getDeclaredMethod("endsWith",
  new Class[] { String.class });

In the invoke() call, we would then supply the string in question inside the object array (which was empty in the above example):

boolean b = (Boolean) lenMethod.invoke(stringObj,
      new Object[] {});

Dealing with primitive parameters

Using reflection to call methods that take primitive parameters can be slightly confusing at first. Let's take the example of calling the two-parameter version of String.substring() via reflection. We might have expected to perform the method lookup as follows:

// This is actually WRONG!
String.class.getDeclaredMethod("substring",
  new Class[] { Integer.class, Integer.class });

Well, if you try this, you'll find that a NoSuchMethodException is thrown. Why? Well, because the above code is looking for a method that takes two Integer objects as its parameters, not to int primitives!

How do we fix this? Well, it turns out that the solution is the little-used .TYPE field that exists on the various wrapper classes (Integer.TYPE, Long.TYPE etc). These fields contain a reference to a special Class object that represents the primitive type. So the correct version of the above line would be:

String.class.getDeclaredMethod("substring",
  new Class[] { Integer.TYPE, Integer.TYPE });

On the other hand, when we invoke the method via Method.invoke(), we pass in a wrapper object for the primitive values:

substringMethod.invoke(stringObj, new Object[] {
  new Integer(0), new Integer(4)
});

However in practice, as of Java 5, the compiler allows us to write the following:

substringMethod.invoke(stringObj, new Object[] {0, 4});

However, note that this is essentially a compiler trick; what actually gets placed into the array are obviously corresponding Integer objects.


Written by Neil Coffey. Copyright © Javamex UK 2009. All rights reserved.