【发布时间】:2021-09-10 04:14:28
【问题描述】:
我正在处理一个项目,该项目需要我直接在现有类文件中为局部变量添加注释,以便它重新创建下面 Java 代码的效果。
@Target({ElementType.LOCAL_VARIABLE, ElementType.TYPE, ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
public class MyClass {
public static void main(String[] args) {
int x = 512;
@MyAnnotation int y = 5;
...
}
}
类文件上javap -p -v输出的注解部分如下所示。
...
RuntimeVisibleTypeAnnotations:
0: #15(): LOCAL_VARIABLE, {start_pc=6, length=26, index=2}
MyAnnotation
为此,我一直在研究 ASM。现在我对 ASM 没有任何经验,但是看到一些例子,我想我对如何进行有了一些想法。这是我的尝试。
public class ASMTransformer {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream(args[0]);
ClassReader cr = new ClassReader(fis);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cr.accept(new ASMClass(cw), ClassReader.EXPAND_FRAMES);
FileOutputStream fos = new FileOutputStream(args[0]);
fos.write(cw.toByteArray());
fos.close();
}
public static class ASMClass extends ClassVisitor {
public ASMClass(ClassVisitor cv) {
super(Opcodes.ASM9, cv);
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name == "main")
return new ASMMethod(super.visitMethod(access, name, desc, signature, exceptions));
else
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
public static class ASMMethod extends MethodVisitor {
public ASMMethod(MethodVisitor mv) {
super(Opcodes.ASM9, mv);
}
public void visitEnd() {
super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
super.visitEnd();
}
}
}
我通过从带注释的类文件中打印出visitLocalVariableAnnotation() 中的一些参数的值来计算它们。但是变量的startLabel[],endLabel[]和index是我无法弄清楚的。
有人可以验证我是否朝着正确的方向前进并帮助我了解这些论点的价值吗?
【问题讨论】:
标签: java annotations bytecode java-bytecode-asm