有没有办法在Java中获取方法参数的名称?

我正在编写小而非常DRY的框架,它严重依赖于元数据。 我想知道是否有办法获取方法参数名称,即给定一些方法

public void a(int myIntParam, String theString) { ... } 

得到字符串"myIntParam""theString"

我知道我可以注释参数,但这不会很好……

 public void a( @Param("myIntParam") int myIntParam, @Param("theString") String theString ) { ... } 

我们为包含参数名称String []的方法创建了一个自定义注释。 这种方法比必须注释每个单独的参数更容易管理。 我们计划添加构建时检查,注释参数名称的数量与参数的数量相匹配,因为它是我们所需要的。

这是一个需要一些调整的脏解决方案。 也许有人可以做得更好。

缺点:

  • 要求您知道已编译的类文件的位置。
  • 它必须使用-g标志进行编译。

码:

 import com.sun.org.apache.bcel.internal.classfile.ClassParser; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.bcel.internal.classfile.LocalVariable; import com.sun.org.apache.bcel.internal.classfile.Method; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { ClassParser parser = new ClassParser("Main.class"); JavaClass clazz = parser.parse(); for (Method m : clazz.getMethods()) { System.out.println("Method: " + m.getName()); int size = m.getArgumentTypes().length; if (!m.isStatic()) { size++; } for (int i = 0; i < size; i++) { LocalVariable variable = m.getLocalVariableTable().getLocalVariable(i); System.out.println(" - Param: " + variable.getName()); } } } public void a(int myIntParam, String theString) { } } 

输出:

$ javac -g Main.java
$ java Main
Method:
- Param: this
Method: main
- Param: args
Method: a
- Param: this
- Param: myIntParam
- Param: theString

不是真的,但是codehaus有这个库可以用于很多目的: http ://paranamer.codehaus.org/

我可能错了…但我不认为参数名称出现在类文件中,所以我猜想没有办法通过reflection得到它们。

当使用调试信息(通过-g选项)编译java代码时,参数的名称存在于类文件中。 然后,类文件包含LocalVariableTable属性(请参阅http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#5956 )。 这包含局部变量的名称,参数只是局部变量。 参数对应于从索引1开始的变量槽(或静态方法的索引0)。

如果你使用的是Spring,那么你很幸运。 只需将其添加到applicationContext.xml:

  

然后你可以在需要的地方注入这个bean:

 @Autowired private ParameterNameDiscoverer parameterNameDiscoverer; Method m = ... String[] names = parameterNameDiscoverer.getParameterNames(m); 

顾名思义,此实现依赖于使用调试信息编译的类。

@bobwienholt是正确的 – 参数名称不会编译到java类中,因此在运行时不可用。

参数名称可通过apt (现在是javac的一部分)获得。