首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java局部变量-如何使用其索引获取变量名称或类型

java局部变量-如何使用其索引获取变量名称或类型
EN

Stack Overflow用户
提问于 2010-12-01 20:25:57
回答 2查看 1.7K关注 0票数 2

我使用的是asm仪表库。使用visitVarInsn,我得到了一个局部变量的索引。我想使用索引并接收更多有用信息,如变量的名称和类型。你知道怎么做吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-01 20:31:04

LocalVariablesSorter.visitLocalVariable方法中获取它。

票数 0
EN

Stack Overflow用户

发布于 2012-06-14 19:43:08

我使用的代码如下:

代码语言:javascript
复制
    private LocalVariableNode getLocalVariableNode(VarInsnNode varInsnNode, MethodNode methodNode) {
        int varIdx = varInsnNode.var;
        int instrIdx = getInstrIndex(varInsnNode);
        List<?> localVariables = methodNode.localVariables;
        for (int idx = 0; idx < localVariables.size(); idx++) {
            LocalVariableNode localVariableNode = (LocalVariableNode) localVariables.get(idx);
            if (localVariableNode.index == varIdx) {
                int scopeEndInstrIndex = getInstrIndex(localVariableNode.end);
                if (scopeEndInstrIndex >= instrIdx) {
                    // still valid for current line
                    return localVariableNode;
                }
            }
        }
        throw new RuntimeException("Variable with index " + varIdx + " and scope end >= " + instrIdx
                + " not found for method " + methodNode.name + "!");
    }

一般的问题是局部变量的索引可以重用。因此,您必须确保为给定的索引获取正确的LocalVariableNode。为此,您需要确保给定的变量在使用它的代码位置仍然有效。问题是您不能使用行号,因为

  1. 开始位置是定义变量后的下一个代码行。由于忽略了空行和注释,因此可以是任何以下行。但由于代码可以重用现有变量,因此这也可以是当前行之前的任何行。
  2. 结束位置可以逐行位于开始位置之前(例如,在循环中)。
  3. 代码可能是在没有行信息的情况下编译的。

所以你需要使用指令索引,它总是正确的。而是AbstractInsnNode中不能从外部访问的内部信息。为了绕过这个问题,我使用了以下代码,它显然破坏了封装,并且由于许多原因而不被推荐。如果你想出更好的办法,让我知道!在此期间,这是可行的:

代码语言:javascript
复制
    private int getInstrIndex(AbstractInsnNode insnNode) {
        try {
            Field indexField = AbstractInsnNode.class.getDeclaredField("index");
            indexField.setAccessible(true);
            Object indexValue = indexField.get(insnNode);
            return ((Integer) indexValue).intValue();
        } catch (Exception exc) {
            throw new RuntimeException(exc);
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4324321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档