如何使用@Target(ElementType.TYPE_USE) 处理注释? [英] How to process annotations with @Target(ElementType.TYPE_USE)?

查看:132
本文介绍了如何使用@Target(ElementType.TYPE_USE) 处理注释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个注解处理器,以确保标有注解的元素是实现特定接口的类的实例,或者是实现特定接口的类型的使用:

I'm implementing an annotation processor to make sure that the elements marked with an annotation are instances of a class that implements a certain interface, or are uses of types that implement a certain interface:

@Documented
@Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AuditSubject {

}

public interface Auditable {
    // methods that provide data for writing a log entry...
}

public class Report implements Auditable {

}

对于被注解的元素,必须在方法执行后创建一个日志条目(使用AOP).例子:

For the annotated elements, a log entry must be created after method execution (using AOP). Examples:

@CreateLogEntry
public Result persist(@AuditSubject Report newReport) {
    // A log entry must be created based on the incoming 'newReport' instance.    
}

@CreateLogEntry
public UpdateResult<@AuditSubject Report> update(Report update) {
    // A log entry must be created based on the updated report, which is not the same instance as 'update' but an equivalent one.
} 

@CreateLogEntry
public Result persistBatch(List<@AuditSubject Report> batch) {
    // A log entry must be created for each element in 'batch' after this method's execution.
}

必须创建日志条目,前提是Report 实现了Auditable;如果没有,则会抛出运行时异常(哎呀,我忘记实现接口了!).因此,注释处理器有助于在编译时捕捉程序员的错误.到目前为止,我已经成功地检查了参数中的所有用途,但没有检查类型用途.来自注解处理器的相关代码如下:

The log entries must be created provided that Report implements Auditable; if it does not, a runtime exception is thrown (Yikes, I forgot to implement the interface!). Thus the annotation processor helps to catch programmer mistakes at compile time. So far I've been successful in checking all uses in parameters, but not in type uses. The relevant code from the annotation processor is as follows:

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    for (Element annotated : roundEnv.getElementsAnnotatedWith(AuditSubject.class)) {
        // Only prints elements with ElementKind.PARAMETER)!
        this.messager.printMessage(Kind.NOTE, TextUtils.replaceParams("annotated: {} ; Kind : {} ; enclosing : {}", annotated,  annotated.getKind(), annotated.getEnclosingElement()));

        if (annotated.getKind() == ElementKind.PARAMETER) {
            // Code here works as expected, raises errors for annotated parameters of classes that don't implement Auditable.
        } else if (annotated.getKind() == ElementKind.WHAT_TO_USE) {
            // What ElementKind do I need to use here?
        }
    }

    return false;
}

仅识别类型为 ElementKind.PARAMETER 的带注释元素(process() 循环中的第一行只打印一行 'newReport')我检查带注释的类型是否实现了 Auditable?没有要使用的ElementKind.TYPE_USE"常量.我一直无法找到有关此事的任何相关信息.感谢您的关注.

Only annotated elements with kind ElementKind.PARAMETER are recognized (the first line in the loop of process() only prints a single line for 'newReport') How can I check that the annotated types implement Auditable? There's no "ElementKind.TYPE_USE" constant to use. I haven't been able to find any relevant information on this matter. Thanks for your attention.

推荐答案

Java 注释处理 API 是在 Java 仅支持声明上的注释时设计的.API仅支持访问声明,如字段、方法、方法参数等.它不访问局部变量声明,也不访问方法体中的其他注解,也不访问类型注解.

The Java annotation processing API was designed when Java only supported annotations on declarations. The API only supports visiting declarations, such as fields, methods, and method parameters. It does not visit local variable declarations, nor other annotations within a method body, nor type annotations.

如果您希望处理类型注解或方法主体内的注解,您将需要编写自己的代码来递归类型或递归检查方法内的代码行.

If you wish to process type annotations or annotations within method bodies, you will need to write your own code to recurse on types or to recurse examining the lines of code within a method.

另一种方法是使用检查器框架之类的工具.它实现了自己的访问者,因此每次出现类型注释时都会调用构建在其上的注释处理器.

An alternative to this is to use a tool like the Checker Framework. It implements its own visitors, and therefore an annotation processor built on it is invoked for every occurrence of a type annotation.

这篇关于如何使用@Target(ElementType.TYPE_USE) 处理注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆