获取方法参数的名称



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

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

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

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

理想情况下,我希望得到参数名称的列表,而不是类型。有办法吗?

参数名是可用的,如果您已经告诉编译器包含它们(用调试信息编译)。Spring有ParameterNameDiscoverer,它可以帮助您获得名称。默认实现使用asm ClassReader

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

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

我找到了另一个解决方案后,标记这个问题作为回答。解决方案是paramamer

的例子:

 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

从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获取方法参数的名称

除了这个答案:"参数名是可用的,如果你已经告诉编译器包含它们"

如果您正在使用Eclipse,请进入project -> properties -> Java Compiler ->检查"存储关于方法参数的信息(可通过反射使用)

在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")传递。稍后,您将能够获得注释并从中提取参数名称。

相关内容

  • 没有找到相关文章

最新更新