Getting the name of a method parameter
Asked Answered
D

8

28

In Java 6, imagine I have the following method signature:

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard)

I would like to know, at runtime, the value that was passed on to slice2 or any other parameter, the important bit here is that I want to get the value by parameter name.

I know how to get the list of parameter types with getParameterTypes or getGenericParameterTypes.

Ideally I would like to get a list of parameter names instead of types. Is there a way to do so?

Donitadonjon answered 20/7, 2011 at 9:39 Comment(2)
This question is about Java 6. For more information about Java 8 onwards, please visit this tutorial about the -parameters option for javacSeadog
I put mustard at the top AND bottom of my sandwich, bool is not specific enough you insensitive clodEfik
C
58

Parameter names are available if you have told the compiler to include them (compile with debug information). Spring has ParameterNameDiscoverer which can help you obtain the names. The default implementation uses asm ClassReader to do so.

With javac you should include the -g argument to include debug information. With Eclipse I think it is there by default; it can be configured using the preferences: Java -> Compiler and then enable "Store information about method parameters (usable via reflection)" (see also this answer).

Some frameworks use this. For example spring-mvc has @RequestParam which defaults to the param name, if resolvable. It also supports explicit naming - @RequestParam("foo") in case no debug information is provided.

Crosspollinate answered 20/7, 2011 at 9:46 Comment(6)
Thanks, I am not using spring. Do you know where I can find some usage examples for ClassReader?Donitadonjon
look at the inspectClass(..) method here src.springframework.org/svn/spring-framework/trunk/…Crosspollinate
Link is broken. inspectClass() seems to have been removed from Spring 3.0.x.Desjardins
Does any one know how can I add the debug information when I'm using Maven?Neutrino
Link broken to Spring source, see github.com/spring-projects/spring-framework/tree/master/…. Helped hint the issue I had for my code (related to long/double variables).Scrofula
How can do this in IntelliJ or Gradle?Xuanxunit
D
11

I have found another solution after marking this question as answered. The solution is Paranamer.

Example:

 Method method = Foo.class.getMethod(...);

 Paranamer paranamer = new CachingParanamer();

 String[] parameterNames = paranamer.lookupParameterNames(method) // throws ParameterNamesNotFoundException if not found

 // or ...

 parameterNames = paranamer.lookupParameterNames(method, false) // will return null if not found
Donitadonjon answered 20/7, 2011 at 21:53 Comment(0)
W
7

Since Java 1.8, this can be done as long as the parameter names are in the class files. Using javac this is done passing the -parameters flag. From the javac help

-parameters    Generate metadata for reflection on method parameters

From IDEs you will need to look at the compiler settings.

If the parameter names are in the class files then here is an example of doing this

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

public class ParameterNamesExamples {

  public static void main(String[] args) throws Exception {
    Method theDoSomethingMethod = ExampleClass.class.getMethods()[0];
    // Now loop through the parameters printing the names
    for(Parameter parameter : theDoSomethingMethod.getParameters()) {
      System.out.println(parameter.getName());
    }
  }

  private class ExampleClass {
    public void doSomething(String myFirstParameter, String mySecondParameter) {
      // No-op
    }
  }
}

The output will depend on if the parameter names are in the class files. If they are the output is:

myFirstParameter
mySecondParameter

If not the output is:

arg0
arg1

More information on this from Oracle can be found at Obtaining Names of Method Parameters

Winged answered 22/3, 2019 at 13:15 Comment(0)
S
4

In addition to this answer: "Parameter names are available if you have told the compiler to include them"

If you're using Eclipse go to project -> properties -> Java Compiler -> check "Store information about method parameters (usable via reflection)

Southward answered 4/5, 2016 at 7:26 Comment(0)
G
2

This is not possible. Class files do not contains the argument names, as you can see with your IDE's autocompletion when the source is not available.

Therefore, the reflection API is not able to give out parameter names.

Glabrescent answered 20/7, 2011 at 9:41 Comment(6)
Any other way, even without reflection?Donitadonjon
I suggest using a HashMap containing variants. Or, (but it seems crafty to me), looking at how the IDE does extract the parameter names from the source JAR.Glabrescent
You would have to log it yourself.Simulation
not entirely true. parameter names can be included (I think the eclipse compiler does that by default, for example)Crosspollinate
"Class files do not contain the argument names". You may be able to do some trickery if you also have the source files. As @kbok mentions, IDEs show argument names on methods if the source is available.Hood
From Java 1.8 onwards this is possible see other answersWinged
C
2

In Java parameter names are not available via reflection.

Corrales answered 20/7, 2011 at 9:42 Comment(0)
L
0

You can simply assign the value of the parameter to another value

Bread slice2;

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard) {
    this.slice2 = slice2;
    System.out.println(this.slice2.getSomething());
}
Lacreshalacrimal answered 20/7, 2011 at 9:44 Comment(0)
A
0

Do you own the code of the method? You could annotate the parameters and pass names as arguments @Param("slice1"). Later you will be able to get the annotation and extract parameter name from it.

Adams answered 20/7, 2011 at 9:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.