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

Java注释-如何在处理器中获取属性和类,java,annotations,Java,Annotations,对于以下自定义Java注释 @CustomAnnotation(clazz=SomeClass.class) public class MyApplicationCode { ... } 我基本上希望能够在编译时获取MyApplicationCode的类对象和clazz参数,以确认一些编码约定的一致性(另一个故事)基本上,我希望能够在注释处理器中访问MyApplicationCode.class和Someclass.class代码。我就快到了,但我遗漏了一些东西。我有 @Target

对于以下自定义Java注释

@CustomAnnotation(clazz=SomeClass.class)
public class MyApplicationCode
{ 
   ... 
}
我基本上希望能够在编译时获取MyApplicationCode的类对象和clazz参数,以确认一些编码约定的一致性(另一个故事)基本上,我希望能够在注释处理器中访问MyApplicationCode.class和Someclass.class代码。我就快到了,但我遗漏了一些东西。我有

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface CustomAnnotation
{
   public Class clazz();
}
然后,我对处理器进行了以下操作:

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?
        }
    }
}
更新:下面的帖子有更多的细节,而且更接近。但问题是,您仍然会得到一个TypeMirror对象,从中提取类对象,但它没有解释:

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

String classname = ((TypeElement)e).getQualifiedName().toString();

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

因此,请检查镜像Api,有关已注释的类/方法/字段的任何相关信息,请检查表示该实例的AnnotateDelete

另请注意:这是我推断出来的信息,所以可能不是事实。

读了这篇文章后,我发现了这一点。这是从2005年开始的,所以现在可能不是最好的方式

APT[…]是一种用于Java的注释处理工具。更具体地说,APT允许您在代码编译过程中插入代码来处理源文件中的注释——在这个过程中,您可以发出注释、警告和错误

  • 有关Oracle文档的更多信息
  • 从甲骨文公司的人那里得到的关于APT的信息
  • 另一次——这次是从2009年开始

这只适用于Oracle的JDK。

我本想告诉您博客的方向,但看起来您已经找到了

我知道你已经知道如何访问MyApplication元素了,所以我不打算讨论这个

您看到的异常实际上包含其中注释属性的类型。因此,您可以在捕获异常时引用注释clazz值:

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)
        {
            CustomAnnotation annotation = e.getAnnotation(CustomAnnotation.class);    

            TypeMirror clazzType = null;
            try {
                annotation.clazz();
            } catch (MirroredTypeException mte) {
                clazzType = mte.getTypeMirror();
            }

            System.out.println(clazzType); // should print out SomeClass

        }
    }
}
公共类CustomAnnotationProcessor扩展了AbstractProcessor
{
私有ProcessingEnvironment ProcessingEnvironment;
@凌驾
公共同步void init(ProcessingEnvironment ProcessingEnvironment)
{
this.processingEnvironment=processingEnvironment;
}
@凌驾

公共布尔过程(设置您认为抑制、重写等注释如何工作?它们必须能够读取类对象;)您是否曾尝试在运行时获取重写批注的实例?您不能,因为它未编译到类文件中。即使在编译完成之前,它也会被丢弃。其语义仅检查是否存在超类方法定义,与源是否已编译无关。以及源文件批注用AnnotatedElement表示,以向您提供有关注释类型的信息,但不是它们的运行时属性,而不是编译时的信息。您可以签出AnnotatedElement源文件吗?与此相关的是我主要引用的4个站点之一。问题是我找不到任何具有该信息的站点。问题是如果你使用字符串等等,这真的很简单,但是当你尝试放置一个类时,它会变得非常复杂。这就是我第一次更新中的链接所讨论的。
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)
        {
            CustomAnnotation annotation = e.getAnnotation(CustomAnnotation.class);    

            TypeMirror clazzType = null;
            try {
                annotation.clazz();
            } catch (MirroredTypeException mte) {
                clazzType = mte.getTypeMirror();
            }

            System.out.println(clazzType); // should print out SomeClass

        }
    }
}