可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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.
回答2:
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
回答3:
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)
回答4:
In Java parameter names are not available via reflection.
回答5:
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.
回答6:
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
回答7:
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());
}
回答8:
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.