在Java 6中,想象一下我有以下方法签名:
public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard)
我想知道,在运行时,传递给slice2
或任何其他参数的值,这里重要的一点是我想通过参数名称获取值。
我知道如何使用getParameterTypes
或getGenericParameterTypes
获取参数类型列表。
理想情况下,我想获得一个参数名称列表而不是类型。有办法吗?
如果您已告知编译器包含它们(使用调试信息进行编译),则可以使用参数名称。春天有ParameterNameDiscoverer
,可以帮助您获得名称。 default implementation使用asm ClassReader
这样做。
使用javac
,您应该包含-g
参数以包含调试信息。使用Eclipse,我认为它默认存在;可以使用首选项配置它:Java - > Compiler,然后启用“存储有关方法参数的信息(可通过反射使用)”(另请参阅this answer)。
一些框架使用它。例如,spring-mvc有@RequestParam
,默认为param名称,如果可解析的话。它还支持显式命名 - @RequestParam("foo")
,以防没有提供调试信息。
在将此问题标记为已回答后,我找到了另一种解决方案解决方案是Paranamer。
例:
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
除了this回答:“如果您告诉编译器包含它们,参数名称可用”
如果您正在使用Eclipse,请转到项目 - >属性 - > Java编译器 - >选中“存储有关方法参数的信息(可通过反射使用)
在Java中,参数名称不能通过反射获得。
这是不可能的。类文件不包含参数名称,因为当源不可用时,您可以通过IDE的自动完成功能看到它们。
因此,反射API无法给出参数名称。
您可以简单地将参数的值分配给另一个值
Bread slice2;
public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard) {
this.slice2 = slice2;
System.out.println(this.slice2.getSomething());
}
你拥有方法的代码吗?您可以注释参数并将名称作为参数@Param("slice1")
传递。稍后您将能够获取注释并从中提取参数名称。
从Java 1.8开始,只要参数名称在类文件中,就可以完成。使用javac
这是通过-parameters
标志。来自javac
的帮助
-parameters Generate metadata for reflection on method parameters
从IDE中,您需要查看编译器设置。
如果参数名称在类文件中,那么这是执行此操作的示例
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
}
}
}
输出将取决于参数名称是否在类文件中。如果他们是输出是:
myFirstParameter
mySecondParameter
如果不是,则输出为:
arg0
arg1
有关Oracle的更多信息,请访问Obtaining Names of Method Parameters