Obtaining Names of Method Parameters

You can obtain the names of the formal parameters of any method or constructor with the method java.lang.reflect.Executable.getParameters. (The classes Method and Constructor extend the class Executable and therefore inherit the method Executable.getParameters.) However, .class files do not store formal parameter names by default. This is because many tools that produce and consume class files may not expect the larger static and dynamic footprint of .class files that contain parameter names. In particular, these tools would have to handle larger .class files, and the Java Virtual Machine (JVM) would use more memory. In addition, some parameter names, such as secret or password, may expose information about security-sensitive methods.

To store formal parameter names in a particular .class file, and thus enable the Reflection API to retrieve formal parameter names, compile the source file with the -parameters option to the javac compiler.

The example illustrates how to retrieve the names of the formal parameters of all constructors and methods of a given class. The example also prints other information about each parameter.

The following command prints the formal parameter names of the constructors and methods of the class . Note: Remember to compile the example ExampleMethods with the -parameters compiler option:

java MethodParameterSpy ExampleMethods

This command prints the following:

Number of constructors: 1
Constructor #1
public ExampleMethods()
Number of declared constructors: 1
Declared constructor #1
public ExampleMethods()
Number of methods: 4
Method #1
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
 Return type: boolean
 Generic return type: boolean
 Parameter class: class java.lang.String
 Parameter name: stringParam
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false
 Parameter class: int
 Parameter name: intParam
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false
Method #2
public int ExampleMethods.varArgsMethod(java.lang.String...)
 Return type: int
 Generic return type: int
 Parameter class: class [Ljava.lang.String;
 Parameter name: manyStrings
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false
Method #3
public boolean ExampleMethods.methodWithList(java.util.List<java.lang.String>)
 Return type: boolean
 Generic return type: boolean
 Parameter class: interface java.util.List
 Parameter name: listParam
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false
Method #4
public <T> void ExampleMethods.genericMethod(T[],java.util.Collection<T>)
 Return type: void
 Generic return type: void
 Parameter class: class [Ljava.lang.Object;
 Parameter name: a
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false
 Parameter class: interface java.util.Collection
 Parameter name: c
 Modifiers: 0
 Is implicit?: false
 Is name present?: true
 Is synthetic?: false

The MethodParameterSpy example uses the following methods from the Parameter class:

Certain constructs are implicitly declared in the source code if they have not been written explicitly. For example, the example does not contain a constructor. A default constructor is implicitly declared for it. The MethodParameterSpy example prints information about the implicitly declared constructor of ExampleMethods:

Number of declared constructors: 1
public ExampleMethods()

Consider the following excerpt from :

public class MethodParameterExamples {
 public class InnerClass { }
}

The class InnerClass is a non-static or inner class. A constructor for inner classes is also implicitly declared. However, this constructor will contain a parameter. When the Java compiler compiles InnerClass, it creates a .class file that represents code similar to the following:

public class MethodParameterExamples {
 public class InnerClass {
 final MethodParameterExamples parent;
 InnerClass(final MethodParameterExamples this$0) {
 parent = this$0; 
 }
 }
}

The InnerClass constructor contains a parameter whose type is the class that encloses InnerClass, which is MethodParameterExamples. Consequently, the example MethodParameterExamples prints the following:

public MethodParameterExamples$InnerClass(MethodParameterExamples)
 Parameter class: class MethodParameterExamples
 Parameter name: this$0
 Modifiers: 32784
 Is implicit?: true
 Is name present?: true
 Is synthetic?: false

Because the constructor of the class InnerClass is implicitly declared, its parameter is implicit as well.

Note:

Constructs emitted by a Java compiler are marked as synthetic if they do not correspond to a construct declared explicitly or implicitly in source code, unless they are class initialization methods. Synthetic constructs are artifacts generated by compilers that vary among different implementations. Consider the following excerpt from :

public class MethodParameterExamples {
 enum Colors {
 RED, WHITE;
 }
}

When the Java compiler encounters an enum construct, it creates several methods that are compatible with the .class file structure and provide the expected functionality of the enum construct. For example, the Java compiler would create a .class file for the enum construct Colors that represents code similar to the following:

final class Colors extends java.lang.Enum<Colors> {
 public final static Colors RED = new Colors("RED", 0);
 public final static Colors BLUE = new Colors("WHITE", 1); private final static values = new Colors[]{ RED, BLUE }; private Colors(String name, int ordinal) {
 super(name, ordinal);
 } public static Colors[] values(){
 return values;
 } public static Colors valueOf(String name){
 return (Colors)java.lang.Enum.valueOf(Colors.class, name);
 }
}

The Java compiler creates three constructors and methods for this enum construct: Colors(String name, int ordinal), Colors[] values(), and Colors valueOf(String name). The methods values and valueOf are implicitly declared. Consequently, their formal parameter names are implicitly declared as well.

The enum constructor Colors(String name, int ordinal) is a default constructor and it is implicitly declared. However, the formal parameters of this constructor (name and ordinal) are not implicitly declared. Because these formal parameters are neither explicitly or implicitly declared, they are synthetic. (The formal parameters for the default constructor of an enum construct are not implicitly declared because different compilers need not agree on the form of this constructor; another Java compiler might specify different formal parameters for it. When compilers compile expressions that use enum constants, they rely only on the public static fields of the enum construct, which are implicitly declared, and not on their constructors or how these constants are initialized.)

Consequently, the example MethodParameterExample prints the following about the enum construct Colors:

enum Colors:
Number of constructors: 0
Number of declared constructors: 1
Declared constructor #1
private MethodParameterExamples$Colors()
 Parameter class: class java.lang.String
 Parameter name: $enum$name
 Modifiers: 4096
 Is implicit?: false
 Is name present?: true
 Is synthetic?: true
 Parameter class: int
 Parameter name: $enum$ordinal
 Modifiers: 4096
 Is implicit?: false
 Is name present?: true
 Is synthetic?: true
Number of methods: 2
Method #1
public static MethodParameterExamples$Colors[]
 MethodParameterExamples$Colors.values()
 Return type: class [LMethodParameterExamples$Colors;
 Generic return type: class [LMethodParameterExamples$Colors;
Method #2
public static MethodParameterExamples$Colors
 MethodParameterExamples$Colors.valueOf(java.lang.String)
 Return type: class MethodParameterExamples$Colors
 Generic return type: class MethodParameterExamples$Colors
 Parameter class: class java.lang.String
 Parameter name: name
 Modifiers: 32768
 Is implicit?: true
 Is name present?: true
 Is synthetic?: false

Refer to the Java Language Specification for more information about implicitly declared constructs, including parameters that appear as implicit in the Reflection API.