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

标签 java annotations

对于下面的自定义Java注解

@CustomAnnotation(clazz=SomeClass.class)
public class MyApplicationCode
{ 
   ... 
}

我基本上希望能够在编译时获取 MyApplicationCode 的 Class 对象和 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?
        }
    }
}

所以我在 process 方法中尝试做的是从下面的原始代码中获取 SomeClass.class 和 MyApplication.class 以在编译时进行一些自定义验证。我似乎一辈子都想不出如何获得这两个值...

@CustomAnnotation(clazz=SomeClass.class)
public class MyApplicationCode

更新:下面的帖子有更多的细节,而且更接近。但问题是您最终仍然得到一个 TypeMirror 对象,从中提取类对象,它没有解释:http://blog.retep.org/2009/02/13/getting-class-values-from-annotations-in-an-annotationprocessor/

更新2:您可以通过以下方式获取MyApplication.class

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

最佳答案

我正要为您指明博客的方向 http://blog.retep.org/2009/02/13/getting-class-values-from-annotations-in-an-annotationprocessor/ ,但看起来您已经找到了那个。

我看到你想出了如何访问 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

        }
    }
}

是的,这是一个完全破解的解决方案,我不确定 API 开发人员为什么决定使用注释处理器功能朝这个方向发展。但是,我已经看到很多人实现了这一点(包括 myself ),并且提到的文章也描述了这种技术。这似乎是目前可以接受的解决方案。

就“获取”MyApplicationCode 和 SomeClass 的类值而言,如果它们是正在编译的类,您将无法这样做。但是,您可以使用 Element 和 TypeMirror 表示对您的类(方法、字段、类名称、存在的注释等)执行一些高级验证

关于Java 注释 - 如何在处理器中获取属性和类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10660363/

相关文章:

java - Hbase客户端扫描程序挂起

java - 使用 Java 泛型和工厂模式返回类型的最佳实践是什么

javascript - 在哪里可以找到 Closure Compiler 的 jQuery Mobile 外部文件?

java - Hibernate注解(金字塔结构-同表)

java - kotlin 注释处理器中的可空类型

java File.separator 在 Windows 上的文件路径中变为 "%"

java - 如何将在可视化编辑器中创建的 Vaadin Composite 组件嵌入到我的网页中?

java - Spring MVC 3 返回内容类型 : text/plain

kotlin - 无法在 intellij 中导入 kotlin.reflect.full.*

latex - PDF文件中的数学注释