27

Java 6中,假设我有以下方法签名:

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

我想知道,在运行时,传递给的值slice2或任何其他参数,这里的重要一点是我想通过参数名称获取值。

我知道如何使用getParameterTypesor获取参数类型列表getGenericParameterTypes

理想情况下,我想获得参数名称而不是类型的列表。有没有办法这样做?

4

8 回答 8

54

如果您告诉编译器包含参数名称(使用调试信息编译),则参数名称可用。Spring 有 ParameterNameDiscoverer它可以帮助您获取名称。默认实现使用 asm来执行此ClassReader操作。

javac您一起应该包含-g参数以包含调试信息。对于 Eclipse,我认为它是默认存在的;它可以使用首选项进行配置:Java -> Compiler,然后启用“存储有关方法参数的信息(可通过反射使用)”(另请参阅此答案)。

一些框架使用它。例如 spring-mvc 具有@RequestParam默认为参数名称(如果可解析)。它还支持显式命名 -@RequestParam("foo")如果没有提供调试信息。

于 2011-07-20T09:46:25.770 回答
11

在将此问题标记为已回答后,我找到了另一种解决方案。解决方案是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
于 2011-07-20T21:53:05.357 回答
5

从 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 的更多信息

于 2019-03-22T13:15:53.277 回答
4

除了这个答案:“如果您告诉编译器包含参数名称,则参数名称可用”

如果您使用的是 Eclipse,请转到项目 -> 属性 -> Java 编译器 -> 选中“存储有关方法参数的信息(可通过反射使用)

于 2016-05-04T07:26:02.263 回答
2

这是不可能的。类文件不包含参数名称,当源不可用时,您可以通过 IDE 的自动完成功能看到这一点。

因此,反射 API 无法给出参数名称。

于 2011-07-20T09:41:57.497 回答
2

在 Java 中,参数名称不能通过反射获得。

于 2011-07-20T09:42:32.127 回答
0

您可以简单地将参数的值分配给另一个值

Bread slice2;

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard) {
    this.slice2 = slice2;
    System.out.println(this.slice2.getSomething());
}
于 2011-07-20T09:44:46.960 回答
0

您是否拥有该方法的代码?您可以注释参数并将名称作为参数传递@Param("slice1")。稍后您将能够获取注释并从中提取参数名称。

于 2011-07-20T09:50:33.460 回答