获取方法参数的名称

时间:2011-07-20 09:39:50

标签: java reflection runtime java-6

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

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

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

我知道如何使用getParameterTypesgetGenericParameterTypes获取参数类型列表。

理想情况下,我想获取参数 names 的列表,而不是类型。有办法吗?

8 个答案:

答案 0 :(得分:44)

如果您已告知编译器包含它们(使用调试信息进行编译),则可以使用参数名称。 Spring有ParameterNameDiscoverer可以帮助你获取名字。 default implementation使用asm ClassReader来执行此操作。

使用javac,您应该包含-g参数以包含调试信息。使用Eclipse,我认为它默认存在;它可以使用首选项进行配置:Java - &gt;编译,然后启用“存储有关方法参数的信息(可通过反射使用)”(另请参阅this answer)。

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

答案 1 :(得分:10)

在将此问题标记为已回答之后,我找到了另一种解决方案。解决方案是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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

除了this回答: “如果您已告知编译器包含它们,则可以使用参数名称”

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

答案 5 :(得分:0)

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

Bread slice2;

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard) {
    this.slice2 = slice2;
    System.out.println(this.slice2.getSomething());
}

答案 6 :(得分:0)

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

答案 7 :(得分:0)

从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