如何在Javassist中创建或检索StackMapTable
在JavassistAPI中,似乎没有直接的方法手动在CodeAttribute属性中添加任何内容 举个例子:如何在Javassist中创建或检索StackMapTable,java,reflection,javassist,Java,Reflection,Javassist,在JavassistAPI中,似乎没有直接的方法手动在CodeAttribute属性中添加任何内容 举个例子: CtMethod m; m.getMethodInfo().getCodeAttribute().setAttribute(???); 这似乎是改变属性的唯一方法。但是,既不可能检索原始属性并修改它们(它返回一个列表od AttributeInfo),也不存在StackMapTable的公共构造函数,这似乎是唯一可接受的输入 有人知道如何做这样的事情吗?对象负责保存表示方法流的字节码
CtMethod m;
m.getMethodInfo().getCodeAttribute().setAttribute(???);
这似乎是改变属性的唯一方法。但是,既不可能检索原始属性并修改它们(它返回一个列表od AttributeInfo),也不存在StackMapTable的公共构造函数,这似乎是唯一可接受的输入
有人知道如何做这样的事情吗?对象负责保存表示方法流的字节码。您可以使用它来迭代表示方法逻辑的字节码
这基本上意味着它表示编译后的方法本身。我知道您可以使用此对象手动修改字节码本身,例如删除两行之间的所有指令:
// erase from line 4 to 6
int startingLineNumber= 6;
// Access the code attribute
CodeAttribute codeAttribute = mymethod.getMethodInfo().getCodeAttribute();
LineNumberAttribute lineNumberAttribute = (LineNumberAttribute) codeAttribute.getAttribute(LineNumberAttribute.tag);
// Index in bytecode array where we start to delete
int firstIndex = lineNumberAttribute.toStartPc(startingLineNumber);
// Index in the bytecode where the first instruction that we keep starts
int secondIndex = lineNumberAttribute.toStartPc(startingLineNumber+2);
// go through the bytecode array
byte[] code = codeAttribute.getCode();
for (int i = firstIndex ; i < secondIndex ; i++) {
// set the bytecode of this line to No OPeration
code[i] = CodeAttribute.NOP;
}
然而,这种方法也可能有相当大的风险,因为您直接处理字节码。最好的办法可能是删除您的方法,然后用您的逻辑添加一个新的方法。这或多或少是我想做的,只是做了一些修改。如果您还记得另一个问题(),这里我只是想用其他方法来设置缺少的参数名称。有了这样一种方法,如果我手动设置AttributeInfo列表,我想我或多或少地解决了它。是的,我记得,我经常阅读所有的
Javassist
问题,无论如何,如果不解决您的问题,我希望我至少能帮您一些想法:)
ClassFile cf = ...;
MethodInfo minfo = cf.getMethod("yourMethod");
Bytecode code = new Bytecode(cf.getConstPool());
// insert your logic here
code.addAload(0);
code.addInvokespecial("java/lang/Object", MethodInfo.nameInit, "()V");
code.addReturn(null);
code.setMaxLocals(1);
MethodInfo minfo = new MethodInfo(cf.getConstPool(), MethodInfo.nameInit, "()V");
minfo.setCodeAttribute(code.toCodeAttribute());