Parameter name reflection

JEP: https://openjdk.java.net/projects/jdk8/features#118

With the new getParameters() method on the class Method (actually inherited from Executable) from the reflection API, it is possible to retrieve the formal parameter names of a method. Earlier, it was only possible to retrieve the number of method parameters and their types.

The prerequisite is that the class which contains the method for which we want to retrieve the parameter names has been compiled with the new javac option -parameters. This is not the default to avoid adding too much overhead to the class files, since this feature of course requires additional meta data (at least the parameter names themselves) to be stored in the class files. The runtime libraries have not been compiled with this option, so we can not retrieve the parameter names of methods from the standard runtime library. Consider the following code:

package com.example;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MethodParameters {
   
   public void someGreatMethod(Number xParam, int yParam, float zParam) {
   }

   // using new Java 8 API
   public void printParameterNames(Method m) {
      System.err.print(m.getName() + "(");
      for (Parameter p : m.getParameters()) {
         System.err.print(" " + p.getName());
      }
      System.err.println(")");
   }

   // using pre Java 8 APIs
   public void printParameterNamesPre8(Method m) {
      System.err.print(m.getName() + "(");
      int paramCount = m.getParameterTypes().length;
      for (int i = 0;  i < paramCount;  i++) {
         System.err.print(" arg" + i);
      }
      System.err.println(")");
   }


   public static void main(String[] args) {
      MethodParameters mp = new MethodParameters();

      try {

         Method m1 = String.class.getDeclaredMethod("regionMatches", 
                   boolean.class, int.class, String.class, int.class, int.class);
         mp.printParameterNames(m1);
         mp.printParameterNamesPre8(m1);
         
         Method m2 = MethodParameters.class.getDeclaredMethod("someGreatMethod",
                   Number.class, int.class, float.class); 
         mp.printParameterNames(m2);
         mp.printParameterNamesPre8(m2);

      } catch (NoSuchMethodException e) {
         e.printStackTrace();
      } catch (SecurityException e) {
         e.printStackTrace();
      }

   }
}

Output:

regionMatches( arg0 arg1 arg2 arg3 arg4)
regionMatches( arg0 arg1 arg2 arg3 arg4)
someGreatMethod( xParam yParam zParam)
someGreatMethod( arg0 arg1 arg2)

Only the third line actually prints the real parameter names, and not artificial ones, since 

  • our own class has been compiled with -parameters
  • It is using the new API introduced with Java8

 The complete source code is also available at https://github.com/afester/CodeSamples/tree/master/Java8/src/com/example.