如何使注释仅在一个目标上弃用

Mar*_*mro 5 java annotations deprecated

我有一个可以添加的注释,METHOD并且TYPE在我们的项目中的数千个地方使用.

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
@Inherited
public @interface RequiredStore{
    Store value();
}
Run Code Online (Sandbox Code Playgroud)

是否可以仅在方法上弃用注释,同时在类型上保持不推荐使用?我希望IDE通知其他开发人员它不应再用于方法,直到我们重构所有现有用法并最终删除该METHOD部分.

如果不可能,除了为类型创建新注释并弃用旧注释之外,还有什么方法可以处理这种情况吗?

kup*_*fic 5

您可以使用注释处理器.

例如,注释及其处理器将放置在其自己的.jar文件中,并作为使用注释的源的依赖项添加.

该自定义.jar将具有以下结构:

src/main/
    java/com/company/annotations/
        RequiredStore.java
        RequiredStoreProcessor.java
    resources/META-INF/services
        javax.annotation.processing.Processor

RequiredStore.java 保持原样.

RequiredStoreProcessor.java 可能看起来像这样:

package com.company.annotations;

import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

@SupportedAnnotationTypes("com.company.annotations.RequiredStore")
public class RequiredStoreProcessor extends AbstractProcessor {
    @Override
    public boolean process(
            Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
        for (Element element 
                : roundEnv.getElementsAnnotatedWith(RequiredStore.class)) {
            if (element.getKind().equals(ElementKind.METHOD)) {
                processingEnv.getMessager().printMessage(
                    Diagnostic.Kind.WARNING,
                    "Using @RequiredStore on methods has been deprecated\n"
                        + "Class: " + element.getEnclosingElement() + "\n"
                        + "Method: " + element.getSimpleName() + "\n");
            }
        }

        // Other processing...

        return false;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }
}
Run Code Online (Sandbox Code Playgroud)

javax.annotation.processing.Processor文件允许javac通过SPI拾取处理器并且只包含

com.company.annotations.RequiredStoreProcessor

最后,.jar将其编译为a 并将其添加到使用注释的类路径中.任何具有该方法的方法@RequiredStore都会产生编译器警告.例如,对于这个班级,

package com.company.business;

import com.company.annotations.RequiredStore;

@RequiredStore
public interface Business {
    @RequiredStore
    public void someMethod();
}
Run Code Online (Sandbox Code Playgroud)

编译器警告是这样的:

warning: Using @RequiredStore on methods has been deprecated
  Class: com.company.business.Business
  Method: someMethod   

至于IDE中的指示,您可能必须编写自定义检查,不幸的是,这取决于所使用的IDE.


笔记:

体面的自定义注释参考:使用Java语言中的注释处理器生成代码