我正在编写小而非常DRY的框架,它非常依赖于元数据。我想知道是否有办法获取方法参数名称,即给定一些方法
public void a(int myIntParam, String theString) { ... }
获取字符串"myIntParam"
和"theString"
。
我知道我可以注释参数,但这不会很好......
public void a(
@Param("myIntParam") int myIntParam,
@Param("theString") String theString
) { ... }
答案 0 :(得分:15)
这是一个需要进行一些调整的脏解决方案。也许有人可以做得更好。
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的一部分)获得。