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

时间:2008-12-19 16:50:24

标签: java reflection

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

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

获取字符串"myIntParam""theString"

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

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

8 个答案:

答案 0 :(得分:15)

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

缺点:

  • 要求您知道已编译类文件的位置。
  • 必须使用-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: <init>
- Param: this
Method: main
- Param: args
Method: a
- Param: this
- Param: myIntParam
- Param: theString

答案 1 :(得分:13)

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

答案 2 :(得分:8)

我可能错了...但我不认为参数名称出现在类文件中,所以我猜想没有办法通过反射来获取它们。

答案 3 :(得分:4)

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

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

<bean class="org.springframework.core.LocalVariableTableParameterNameDiscoverer"/>

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

@Autowired
private ParameterNameDiscoverer parameterNameDiscoverer;

Method m = ...
String[] names = parameterNameDiscoverer.getParameterNames(m);

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

答案 6 :(得分:2)

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

答案 7 :(得分:0)

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