[英]Does Reflections library ignore the RetentionPolicy
For understanding of the Java annotations I tried some hands on and got few doubts, even though looking at execution I am still confused. 为了理解Java批注,尽管尝试了执行,但我仍然感到困惑,我尝试了一些尝试并获得了很少的疑问。 Here is what I am doing.
这是我在做什么。 Define a Annotation
定义注释
@Retention(RetentionPolicy.CLASS)
@Target(value=ElementType.TYPE)
public @interface Command {
}
Now I initialize the commands 现在我初始化命令
Reflections reflections = new Reflections(CMDS_PACKAGE);
Set<Class<?>> allClasses = reflections.getTypesAnnotatedWith(Command.class); // line 2
for (Class clazz : allClasses) {
MYCommand cmd = (MYCommand) clazz.newInstance();
System.out.println(cmd.getClass().getAnnotation(Command.class));// line 6
log.info("loading Command [ {} ]", clazz.getCanonicalName());
}
when I run the program line 6 displays null
. 当我运行程序时,第6行显示
null
。 When the policy is RetentionPolicy.RUNTIME
line 6 displays the correct Command. 当策略为
RetentionPolicy.RUNTIME
第6行显示正确的命令。
During this process the line 2 is still giving me correct Annotated class irrespective of policy. 在此过程中,第2行仍然为我提供了正确的带注释的类,与策略无关。 So does it mean that the Reflection Library is ignoring the
RetentionPolicy
这是否意味着反射库忽略了
RetentionPolicy
I am really confused even though reading most of tutorials. 即使阅读了大多数教程,我也很困惑。
The question for me actually is that , why is this different behaviour? 对我来说实际上的问题是,为什么这种不同的行为? When annotated with
RetentionPolicy.CLASS
policy It should not have given me at runtime. 用
RetentionPolicy.CLASS
策略注释时,它在运行时不应该给我。 Is my understanding wrong or can anyone please share there valuable inputs on the understanding of these both. 我的理解是错误的,还是任何人都可以在那里分享对这两者的理解的宝贵意见。
In the first place, the RetentionPolicy
dictates what a conforming compiler has to do. 首先,
RetentionPolicy
规定了合格的编译器必须执行的操作。 Annotation
s with RetentionPolicy.SOURCE
do not make it into the class file while the other two, RetentionPolicy.CLASS
and RetentionPolicy.RUNTIME
, are stored within the class file but using different attributes to allow to make a distinction between them when reading the class file. 带有
RetentionPolicy.SOURCE
Annotation
不会进入类文件,而其他两个RetentionPolicy.CLASS
和RetentionPolicy.RUNTIME
存储在类文件中,但是使用不同的属性允许在读取类文件时进行区分。
The documentation of RetentionPolicy.CLASS
says: RetentionPolicy.CLASS
的文档说:
Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.
注释由编译器记录在类文件中,但VM在运行时无需保留。 This is the default behavior.
这是默认行为。
Here, the responsibility is clearly documented, the VM shall not retain them and the Reflection API built into the JRE conforms to it. 在此,明确记录了责任, VM不应保留责任,并且JRE内置的Reflection API与此相符。 Though “need not be retained” does not sound like a strong requirement.
尽管“不需要保留”听起来并不像是一个强烈的要求。
But 3rd party libraries like the Reflection Library you are using are free to implement whatever they want when parsing a class file. 但是,您正在使用的第三方库(例如反射库)可以自由地解析语法文件时实现他们想要的任何东西。 Since the documentation for the method you have called simply says: “get types annotated with a given annotation”, the behavior isn't wrong as the type has that annotation.
由于您调用的方法的文档仅说:“获取使用给定注释进行注释的类型”,因此行为没有错,因为该类型具有该注释。
And you are able to find out the RetentionPolicy
of that Annotation
even before invoking that method by analyzing the Annotations
of the Annotation
. 你能找出
RetentionPolicy
是的Annotation
甚至通过分析调用该方法之前Annotations
的的Annotation
。 So it makes no sense invoking the method when you already know that the annotation has the RetentionPolicy.CLASS
and then bother because the method does something instead of nothing. 因此,当您已经知道注释具有
RetentionPolicy.CLASS
并随后麻烦时,调用该方法是没有意义的,因为该方法执行的是操作而不是不执行任何操作。
But, of course, it would be better if that behavior was documented completely. 但是,当然,最好将这种行为完整记录下来。 So you might ask the author of that 3rd party library to improve the documentation.
因此,您可以要求该第三方库的作者改进文档。
Yes, the Reflections library (not Reflection, but Reflection* s *) does ignore the visibility of annotations by default. 是的, 反射库 (不是反射,而是反射* s *)默认情况下不会忽略注释的可见性。 This can be changed using the org.reflections.adapters.JavassistAdapter#includeInvisibleTag flag.
可以使用org.reflections.adapters.JavassistAdapter#includeInvisibleTag标志进行更改。 Something like:
就像是:
JavassistAdapter mdAdapter = new JavassistAdapter();
mdAdapter.includeInvisibleTag = false;
new Reflections(new ConfigurationBuilder()
...
.setMetadataAdapter(mdAdapter)
...
Another option would be to use the JavaReflectionAdapter instead. 另一种选择是改为使用JavaReflectionAdapter。
HTH HTH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.