我有一个CtMethod
实例,但我不知道如何从中获取参数名称(不是类型)。我试过了getParameterTypes
,但它似乎只返回了类型。
我认为这是可能的,因为我使用的库没有源代码,只有类文件,我可以在IDE中看到方法参数的名称。
答案 0 :(得分:8)
确实可以检索参数的名称,但仅当代码已使用调试符号编译时,否则您将无法执行此操作。
要检索此信息,您必须访问方法的本地变量表。有关此数据结构的详细信息,建议您查看4.7.13. The LocalVariableTable Attribute的jvm spec部分。正如我通常所说的那样,JVM规范可能看起来很笨重但是当你在这个级别工作时它是一个非常宝贵的朋友!
CtMethod method = .....;
MethodInfo methodInfo = method.getMethodInfo();
LocalVariableAttribute table = methodInfo.getCodeAttribute().getAttribute(javassist.bytecode.LocalVariableAttribute.tag);
现在,您已在table
变量中选择了本地变量属性。
int numberOfLocalVariables = table.tableLenght();
现在请记住有关numberOfLocalVariables
中数字的两件事:
this
变量。本地变量表的顺序如下:
|this (if non static) | arg1 | arg2 | ... | argN | var1 | ... | varN|
现在,如果您想要检索上一个示例中的arg2名称,那么它就是数组中的第3个位置。因此,您执行以下操作:
// remember it's an array so it starts in 0, meaning if you want position 3 => use index 2
int frameWithNameAtConstantPool = table.nameIndex(2);
String variableName = methodInfo.getConstPool().getUtf8Info(frameAtConstantPool)
现在,您的变量名称位于variableName
。
旁注:我带您浏览了风景路线,以便您可以了解更多有关Java(和javassists)内部的信息。但是已经有工具可以为你做这种操作,我至少可以记住一个名为paranamer的名字。您可能也想看看它。
希望它有所帮助!
答案 1 :(得分:3)
如果您实际上并不想要参数的名称,但只是希望能够访问它们,您可以使用" $ 1,$ 2,..."见in this tutorial。
答案 2 :(得分:0)
如果您进行转换,它可以与Javaassist 3.18.2(以及以后的至少3.19)一起使用,如下所示:
LocalVariableAttribute nameTable = (LocalVariableAttribute)methodInfo.getCodeAttribute().getAttribute(LocalVariableAttribute.tag);
答案 3 :(得分:0)
Paranamer具有可用于检索参数名称的方法,即使该参数名称未使用调试符号进行编译也是如此。我已经用过了,对我来说效果很好。试试看。 paranamer link