Core Java

Constructor/Method Parameters Metadata Available Via Reflection in JDK 8

One of the lesser advertised new features of JDK 8 is the optional ability to include parameter metadata in compiled Java classes [JDK Enhancement Proposal (JEP) 118]. This feature allows Java applications to access this parameter metadata information at runtime via reflection.

The Java TutorialsReflection API trail includes a lesson called Obtaining Names of Method Parameters that discusses and demonstrates how to apply this new feature in Java 8. The lesson includes an example Java class MethodParameterSpy that can be run against a provided Java class to indicate characteristics of method and constructor parameters. This lesson also emphasizes that this is an optional feature because storing additional parameter metadata in .class files increases the size of those files. The lesson also points out that there may be some cases where parameter names have sensitive information that the developer does not want available in the compiled .class files.

The additional parameter metadata can be included in .class files compiled in Java 8 by passing the -parameters option to the javac compiler. This -parameters option is also shown when one types javac -help as shown in the next screen snapshot.


The Oracle TechNotes page on javac indicates how this additional method/constructor parameter data can be accessed at runtime: “Stores formal parameter names of constructors and methods in the generated class file so that the method java.lang.reflect.Executable.getParameters from the Reflection API can retrieve them.” The following code snippet (class called ParameterDisplayer) demonstrates this (emphasis is on the displayParametersMetadata(String[]) method).

package dustin.examples.jdk8;

import static java.lang.System.out;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

 * Uses JDK 8 Parameter class to demonstrate metadata related to the parameters
 * of the methods and constructors of the provided class (includes private,
 * protected, and public methods, but does not include methods inherited from
 * parent classes; those classes should be individually submitted).
 * @author Dustin
public class ParameterDisplayer
   private static void displayParametersMetadata(final String[] classesNames)
      for (final String className : classesNames)
            final Class clazz = Class.forName(className);

            // Get all class's declared methods (does not get inherited methods)
            final Method[] declaredMethods = clazz.getDeclaredMethods();
            for (final Method method : declaredMethods)
                    "Method " + method.toGenericString()
                  + " has " + method.getParameterCount() + " Parameters:");
               int parameterCount = 0;
               final Parameter[] parameters = method.getParameters();
               for (final Parameter parameter : parameters)
                       "\targ" + parameterCount++ + ": "
                     + (parameter.isNamePresent() ? parameter.getName() : "Parameter Name not provided,")
                     + (isParameterFinal(parameter) ? " IS " : " is NOT ")
                     + "final, type " + parameter.getType().getCanonicalName()
                     + ", and parameterized type of " + parameter.getParameterizedType()
                     + " and " + (parameter.isVarArgs() ? "IS " : "is NOT ")
                     + "variable." );
         catch (ClassNotFoundException cnfEx)
            out.println("Unable to find class " + className);

   private static void writeHeader(final String headerText)
      out.println("= " + headerText);

    * Indicate whether provided Parameter is final.
    * @param parameter Parameter to be tested for 'final' modifier.
    * @return {@code true} if provided Parameter is 'final'.
   private static boolean isParameterFinal(final Parameter parameter)
      return Modifier.isFinal(parameter.getModifiers());

   public static void main(final String[] arguments)
      if (arguments.length < 1)
         out.println("You must provide the fully qualified name of at least one class.");


I had initially thought about running this class against a well-known class of the JDK, but realized that would not be too helpful because those classes are not likely to have been built with the -parameters option. Therefore, I have created a simple example class to aid with the demonstration. It is called ManyMethods and is shown next.

package dustin.examples.jdk8;

import java.util.List;

 * Class with numerous methods intended to be used in demonstrating JDK 8's new
 * Parameter class.
 * @author Dustin
public class ManyMethods
   public ManyMethods() {}

   private void addArrayOfStrings(String[] strings) {}

   private void addManyStrings(final String ... strings) {}

   private void addListOfStrings(final List<String> strings) {}

   public String toString()
      return "ManyMethods";

The next two screen snapshots demonstrate running ParameterDisplayer against instances of ManyMethods compiled without and with the -parameters option. The most notable differences are that the parameter names are not provided when compiled without the -parameters option. Also, there is no trusted information on whether the parameter is final when compiled without the -parameters option. The Parameter.getModifiers() method does not include final when compiled without -parameters whether or not the parameter is actually final.



The ParameterDisplayer class uses Parameter.isNamePresent() to programmatically identify that the parameter name is not present (when not compiled with the -parameters option). Had that check not been made, the parameter name returned by Parameter.getName() would have been “arg” plus the number of the parameter (arg0 for the first parameter, arg1 for the second parameter, and so on).

Two of the three methods in ManyMethods class that had a parameter had the final modifier on that parameter. These cases were correctly identified by reflection using Parameter.getModifiers() only when the class was compiled with the -parameters option.

Slightly Related Side Note: Sun/Oracle tools documentation has always consisted of a “windows” page and a “solaris” page, with the latter typically being used to describe how the particular tool works on all flavors on Linux and Unix. I noted that this has changed with the Java 8 documentation. This documentation still has a “windows” version, but the Unix/Linux version now has “unix” in its URL. To illustrate this, here are the URLs for Java SE 7 and Java SE 8 javac tool pages:

Returning to the new (with Java 8) Parameter class, it’s worth noting that there is an increase in compiled .class files that store this additional parameter metadata. For my ManyMethods class shown above, the .class file was enlarged from 909 bytes to 961 bytes.

Constructor, like Method, extends Executable, and so the Constructor class enjoys the same getParameters method as Method. Java 8 provides more detail on method and constructor parameters when the code is explicitly compiled with that extra information.

Want to know how to develop your skillset to become a Java Rockstar?

Join our newsletter to start rocking!

To get you started we give you our best selling eBooks for FREE!


1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design


and many more ....


Receive Java & Developer job alerts in your Area

I have read and agree to the terms & conditions


Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Back to top button