问题描述
伙计们,我无法使用asm MethodVisitor访问局部变量批注,我不知道该怎么办,请帮助我,我想获取值“ in method”,但是MethodVisitor visitLocalVariableAnnotation()方法没有被调用ASM逻辑,这是我的代码:
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.LOCAL_VARIABLE})
public @interface SendEvent {
String value() default "hello every";
}
public class AnnotationTest {
public void test() {
@SendEvent(value = "in method")
EventBase base = new EventBase();
}
}
public class AsmMethodVisitor extends MethodVisitor implements Opcodes {
public AsmMethodVisitor(MethodVisitor methodVisitor) {
super(ASM7,methodVisitor);
System.out.println("== AsmMethodVisitor");
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,TypePath typePath,Label[] start,Label[] end,int[] index,String descriptor,boolean visible) {
System.out.println("== visitLocalVariableAnnotation");
return super.visitLocalVariableAnnotation(typeRef,typePath,start,end,index,descriptor,visible);
}
}
解决方法
这是预期的,根据JLS 9.6.4.2,此信息根本不会保留在类文件中:
9.6.4.2。 @Retention
注释只能在源代码中出现,或者它们可以以类或接口的二进制形式出现。通过Java SE Platform的反射库,以二进制形式存在的注释在运行时可能会或可能会不可用。注释类型
java.lang.annotation.Retention
用于在这些可能性中进行选择。如果注释
a
对应于类型T,并且T具有(元)注释m
对应于java.lang.annotation.Retention
,则:
如果
m
的元素值为java.lang.annotation.RetentionPolicy.SOURCE
,则Java编译器必须确保a出现在类或接口的二进制表示形式中。 / p>如果
m
的元素值为java.lang.annotation.RetentionPolicy.CLASS
或java.lang.annotation.RetentionPolicy.RUNTIME
,则Java编译器必须确保在类或接口的二进制表示形式中表示a。出现,除非注释本地变量声明或注释lambda表达式的形式参数声明。在声明局部变量或在lambda表达式的形式参数上的注释从未保留在二进制表示中。 ,如果注释类型指定了适当的保留策略,则在二进制表示形式中保留有关局部变量类型或lambda表达式的形式参数类型的注释。
请注意,使用
@Target(java.lang.annotation.ElementType.LOCAL_VARIABLE)
和@Retention(java.lang.annotation.RetentionPolicy.CLASS)
或@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
对注释类型进行元注释是非法的。如果
m
的元素值为java.lang.annotation.RetentionPolicy.RUNTIME
,则Java SE Platform的反射库必须在运行时使a
可用。如果T没有对应于
java.lang.annotation.Retention
的(元注释)m,那么Java编译器必须将T视为确实具有这样的元注释m,其元素值为{{ 1}}。
(重点是我的)
ASM根本无法针对不存在的信息发出事件。