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

查看:213
本文介绍了如何使用@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.

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

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天全站免登陆