Java注解-如何在处理器中获取属性和类

Ste*_*ier 5 java annotations

对于以下自定义Java注释

@CustomAnnotation(clazz=SomeClass.class)
public class MyApplicationCode
{ 
   ... 
}
Run Code Online (Sandbox Code Playgroud)

我基本上希望能够在编译时获取MyApplicationCode的Class对象和clazz参数,以确认一些编码约定的一致性(另一个故事)。基本上,我希望能够在注释处理器中访问MyApplicationCode.class和Someclass.class代码。我快到了,但我想念什么。我有

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface CustomAnnotation
{
   public Class clazz();
}
Run Code Online (Sandbox Code Playgroud)

然后我有处理器:

public class CustomAnnotationProcessor extends AbstractProcessor
{
    private ProcessingEnvironment processingEnvironment;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment)
    {
        this.processingEnvironment = processingEnvironment;
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment environment)    
    {
        Set<? extends Element> elements = environment.getElementsAnnotatedWith(ActionCommand.class);

        for(Element e : elements)
        {
            Annotation annotation = e.getAnnotation(CustomAnnotation.class);
            Class clazz = ((CustomAnnotation)annotation).clazz();        

            // How do I get the actual CustomAnnotation clazz?
            // When I try to do clazz.getName() I get the following ERROR:
            // Attempt to access Class object for TypeMirror SomeClass

            // Also, how do I get the Class object for the class that has the annotation within it?
            // In other words, how do I get MyApplicationCode.class?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我要在处理方法中尝试的是从下面的原始代码中获取SomeClass.class和MyApplication.class,以便在编译时进行一些自定义验证。我一生似乎无法弄清楚如何获得这两个价值...

@CustomAnnotation(clazz=SomeClass.class)
public class MyApplicationCode
Run Code Online (Sandbox Code Playgroud)

更新:以下文章有更多详细信息,并且更加接近。但是问题在于,您仍然最终得到了一个TypeMirror对象,从该对象中可以提取该类对象,但它并没有解释:http : //blog.retep.org/2009/02/13/getting-class-values来自注释处理器中的注释/

Update2:您可以通过执行以下操作获取MyApplication.class

String classname = ((TypeElement)e).getQualifiedName().toString();
Run Code Online (Sandbox Code Playgroud)

mar*_*ess -2

现在是编译时间。我认为编译器甚至还没有完成源代码的编译。您从 AnnotatedElement 实例检索此类信息,该实例将为您提供已注释的类型的相关信息,但不是其运行时属性,因为虚拟机尚未加载相关类文件,所以该属性尚不可用。而且编译器甚至不能保证运行在java虚拟机下,因此不强制要求能够加载class文件。它的要求只是能够生成任何特定虚拟机都可以读取的字节码。

因此,请检查镜像 Api,并查看有关您已注释的类/方法/字段的任何相关信息,请检查代表该实例的 AnnotatedElement。

顺便说一句:这些信息只是我推理出来的,所以它可能不是事实。