Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I obtain method parameter name using Java reflection?

People also ask

Which method is used to fetch the parameter types using method parameter reflection?

reflect package is used to fetch the parameter types using method parameter reflection. Reflection is a process of analyzing and modifying all capabilities of class at runtime.

Which method is used to get methods using reflection?

The getConstructors() method is used to get the public constructors of the class to which an object belongs. The getMethods() method is used to get the public methods of the class to which an object belongs.

How do you find the parameter of a method?

The getParameterTypes() returns an array of length 0 if the method object takes no parameters. Parameters: The method does not take any parameters. Return Value: The method returns an array of Class object that represents the formal parameter types of the method object, in declaration order.


In Java 8 you can do the following:

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public final class Methods {

    public static List<String> getParameterNames(Method method) {
        Parameter[] parameters = method.getParameters();
        List<String> parameterNames = new ArrayList<>();

        for (Parameter parameter : parameters) {
            if(!parameter.isNamePresent()) {
                throw new IllegalArgumentException("Parameter names are not present!");
            }

            String parameterName = parameter.getName();
            parameterNames.add(parameterName);
        }

        return parameterNames;
    }

    private Methods(){}
}

So for your class Whatever we can do a manual test:

import java.lang.reflect.Method;

public class ManualTest {
    public static void main(String[] args) {
        Method[] declaredMethods = Whatever.class.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals("aMethod")) {
                System.out.println(Methods.getParameterNames(declaredMethod));
                break;
            }
        }
    }
}

which should print [aParam] if you have passed -parameters argument to your Java 8 compiler.

For Maven users:

<properties>
    <!-- PLUGIN VERSIONS -->
    <maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>

    <!-- OTHER PROPERTIES -->
    <java.version>1.8</java.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <!-- Original answer -->
                <compilerArgument>-parameters</compilerArgument>
                <!-- Or, if you use the plugin version >= 3.6.2 -->
                <parameters>true</parameters>
                <testCompilerArgument>-parameters</testCompilerArgument>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

For more information see following links:

  1. Official Java Tutorial: Obtaining Names of Method Parameters
  2. JEP 118: Access to Parameter Names at Runtime
  3. Javadoc for Parameter class

To summarize:

  • getting parameter names is possible if debug information is included during compilation. See this answer for more details
  • otherwise getting parameter names is not possible
  • getting parameter type is possible, using method.getParameterTypes()

For the sake of writing autocomplete functionality for an editor (as you stated in one of the comments) there are a few options:

  • use arg0, arg1, arg2 etc.
  • use intParam, stringParam, objectTypeParam, etc.
  • use a combination of the above - the former for non-primitive types, and the latter for primitive types.
  • don't show argument names at all - just the types.

The Paranamer library was created to solve this same problem.

It tries to determine method names in a few different ways. If the class was compiled with debugging it can extract the information by reading the bytecode of the class.

Another way is for it to inject a private static member into the bytecode of the class after it is compiled, but before it is placed in a jar. It then uses reflection to extract this information from the class at runtime.

https://github.com/paul-hammant/paranamer

I had problems using this library, but I did get it working in the end. I'm hoping to report the problems to the maintainer.


see org.springframework.core.DefaultParameterNameDiscoverer class

DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] params = discoverer.getParameterNames(MathUtils.class.getMethod("isPrime", Integer.class));