java - 如何在 ASM 中访问方法内部的注解
问题描述
伙计们,我无法使用asm MethodVisitor访问局部变量注释,我不知道该怎么做,请帮助我,我想获取“方法中”的值,但是ASM逻辑没有调用MethodVisitor visitLocalVariableAnnotation() 方法,这是我的代码:
@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。@保留
注释可能只存在于源代码中,或者它们可能以类或接口的二进制形式存在。以二进制形式存在的注解在运行时可能通过 Java SE 平台的反射库可用,也可能不可用。注释类型
java.lang.annotation.Retention
用于在这些可能性中进行选择。如果一个注解
a
对应一个类型 T,并且 T 有一个m
对应于的(元)注解java.lang.annotation.Retention
,那么:
如果
m
有一个值为 的元素java.lang.annotation.RetentionPolicy.SOURCE
,则 Java 编译器必须确保 a 不存在于出现 a 的类或接口的二进制表示中。如果
m
有一个值为java.lang.annotation.RetentionPolicy.CLASS
or 的元素java.lang.annotation.RetentionPolicy.RUNTIME
,则 Java 编译器必须确保 a 以出现 a 的类或接口的二进制表示形式表示,除非 a 注释局部变量声明或 a 注释 lambda 的形式参数声明表达。声明局部变量或声明 lambda 表达式的形式参数的注释永远不会保留在二进制表示中。相反,如果注释类型指定了合适的保留策略,则有关局部变量类型或 lambda 表达式的形式参数类型的注释将保留在二进制表示中。
@Target(java.lang.annotation.ElementType.LOCAL_VARIABLE)
请注意,使用and@Retention(java.lang.annotation.RetentionPolicy.CLASS)
或对注释类型进行元注释并不违法@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
。如果
m
有一个值为 的元素,java.lang.annotation.RetentionPolicy.RUNTIME
Java SE 平台的反射库必须a
在运行时可用。如果 T 没有对应于 的(元)注释 m
java.lang.annotation.Retention
,则 Java 编译器必须将 T 视为它确实具有这样的元注释 m,其中元素的值为java.lang.annotation.RetentionPolicy.CLASS
。
(强调我的)
ASM 不能简单地为不存在的信息发出事件。
推荐阅读
- flutter - How to resolve SocketException,errorno=7 in flutter Using Alert or SnackBar
- python - regex works fine on the limited input but script hangs when whole input file is given
- java - How to run .bat file when deploying java spring boot project on tomcat?
- domain-driven-design - DDD:DTO 和参数对象
- android - 在后台启动前台摄像头录制服务
- jenkins - Jenkins 作业失败 java.lang.NullPointerException:无法在空对象上调用方法 getAt()
- android - Flutter App 总是先触发 onNotification 动作
- openstack - RBD used size小于C盘实际使用大小
- r - Microsoft Graph API - sendMail API 错误 - “请求的用户 'foobar@private.com' 无效。”
- tensorflow - 如何使用tensorflow/models/research/object_detection/models下的模型