【发布时间】:2019-10-07 18:03:58
【问题描述】:
自 Java 9 起,以 LOCAL_VARIABLE 为目标的注解的保留方式发生了变化。 Now the bytecode representation will hold information about annotated local variables in each method. 另外,规范声明If m has an element whose value is java.lang.annotation.RetentionPolicy.RUNTIME, the reflection libraries of the Java SE Platform must make a available at run time.,如果我理解正确的话,它确认至少方法的局部变量上的注释应该可以通过反射获得。
但是,我一直在尝试使用反射来查找注释(或带注释的局部变量,或其值),但没有成功。
因此,是否有人知道如何执行此操作或是否可能?我正在使用 java 11。
例如,这是我的 Main 类,我尝试从测试方法中获取 @Parallel 注释。
public class Main {
public static void main(String[] args) {
try {
System.out.println("Main.class.getDeclaredMethod(\"test\").getAnnotations().length = " +
Main.class.getDeclaredMethod("test").getAnnotations().length);
System.out.println("Main.class.getDeclaredMethod(\"test\").getDeclaredAnnotations().length = " +
Main.class.getDeclaredMethod("test").getDeclaredAnnotations().length);
Annotation annotation = Main.class.getDeclaredMethod("test").getAnnotation(Parallel.class);
System.out.println("annotation = " + annotation);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
void test() {
@Parallel int a = 2;
@Parallel int b = 4;
}
}
这是我的注释实现。我只是将所有内容添加为目标,因为我只是在测试它:
@Target({ ElementType.LOCAL_VARIABLE, ElementType.TYPE, ElementType.TYPE_USE, ElementType.TYPE_PARAMETER,
ElementType.FIELD, ElementType.PARAMETER, ElementType.PACKAGE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {
}
运行javap -l -v -c -s Main.class 将显示:
void test();
descriptor: ()V
flags: (0x0000)
Code:
stack=1, locals=3, args_size=1
0: iconst_2
1: istore_1
2: iconst_4
3: istore_2
4: return
LineNumberTable:
line 22: 0
line 24: 2
line 25: 4
RuntimeVisibleTypeAnnotations:
0: #27(): LOCAL_VARIABLE, {start_pc=2, length=3, index=1}
Parallel
1: #27(): LOCAL_VARIABLE, {start_pc=4, length=1, index=2}
Parallel
很明显,关于局部变量的注释信息在那里,我只是不知道反射是否能够检索它(或者是否有任何其他方法可以在运行时获取它)
【问题讨论】:
-
据我了解,您不能反射性地访问局部变量。
-
我不一定对使用反射查找局部变量的名称或其值感兴趣。我想获取方法局部变量的注释。
-
如果你真的需要这样的注解,你可以尝试使用一些字节码处理库,比如Javassist或者更底层的ASM
标签: java reflection annotations