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.MethodParameterSpy
The following command prints the formal parameter names of the constructors and methods of the class
. Note: Remember to compile the example ExampleMethodsExampleMethods 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:
getType: Returns a
Class object that identifies the declared type for the parameter.
getName: Returns the name of the parameter. If the parameter's name is present, then this method returns the name provided by the .class file. Otherwise, this method synthesizes a name of the form argN, where N is the index of the parameter in the descriptor of the method that declares the parameter.
For example, suppose you compiled the class ExampleMethods without specifying the -parameters compiler option. The example MethodParameterSpy would print the following for the method ExampleMethods.simpleMethod:
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
Return type: boolean
Generic return type: boolean
Parameter class: class java.lang.String
Parameter name: arg0
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
Parameter class: int
Parameter name: arg1
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
getModifiers : Returns an integer that represents various characteristics that the formal parameter possesses. This value is the sum of the following values, if applicable to the formal parameter:
| Value (in decimal) | Value (in hexadecimal | Description |
|---|---|---|
| 16 | 0x0010 | The formal parameter is declared final |
| 4096 | 0x1000 | The formal parameter is synthetic. Alternatively, you can invoke the method isSynthetic. |
| 32768 | 0x8000 | The parameter is implicitly declared in source code. Alternatively, you can invoke the method isImplicit |
isImplicit: Returns true if this parameter is implicitly declared in source code. See the section Implicit and Synthetic Parameters for more information.
isNamePresent: Returns true if the parameter has a name according to the .class file.
isSynthetic: Returns true if this parameter is neither implicitly nor explicitly declared in source code. See the section Implicit and Synthetic Parameters for more information.
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 ExampleMethodsMethodParameterSpy example prints information about the implicitly declared constructor of ExampleMethods:
Number of declared constructors: 1 public ExampleMethods()
Consider the following excerpt from
:MethodParameterExamples
public class MethodParameterExamples {
public class InnerClass { }
}
The class InnerClass is a non-static
nested class 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:
InnerClass constructor is both final (16) and implicit (32768).$); however, by convention, dollar signs are not used in variable names.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
:MethodParameterExamples
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.