gpt4 book ai didi

java - 如何像FunctionalInterface一样实现注解来限制成员函数的数量、函数类型等?

转载 作者:行者123 更新时间:2023-11-30 06:45:39 24 4
gpt4 key购买 nike

Java内部有很多注解,如SuppressWarningFunctionalInterface等,可以通过注解限制类的成员、扩展类甚至指定编译器选项,但是普通程序员如何编写这样的注释呢?

我搜索了注释主题,我所能找到的只是向注释添加一些元值,如 this ,以及如何使用注释,但我找不到任何解释如何实现高级注释的内容。任何指示都会有所帮助。

最佳答案

您正在寻找的是编译时注释

基本上可以根据它的RetentionPolicy来进行注解处理。根据 Java docs ,有 3 种类型的 RetentionPolicy -

CLASS Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.

RUNTIME Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.

SOURCE Annotations are to be discarded by the compiler.

编译时注释处理与 RetentionPolicy.SOURCE 相关,因为您想在编译时对源文件进行处理,类似于 @Override 等其他注释。

下面是一个简单的编译时注解处理器的例子——

  1. 创建 Maven 项目 - Annotation_Compile_Time -

    (A) 在本项目中创建编译时Annotation MyAnnotation -

    package xxx;

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Documented
    @Target(ElementType.TYPE)
    @Inherited
    @Retention(RetentionPolicy.SOURCE)
    public @interface MyAnnotation {

    }

    (B) 创建注解处理器MyAnnotationProcessor -

    package xxx;

    import java.util.Set;

    import javax.annotation.processing.AbstractProcessor;
    import javax.annotation.processing.RoundEnvironment;
    import javax.annotation.processing.SupportedAnnotationTypes;
    import javax.annotation.processing.SupportedSourceVersion;
    import javax.lang.model.SourceVersion;
    import javax.lang.model.element.Element;
    import javax.lang.model.element.TypeElement;
    import javax.tools.Diagnostic;

    @SupportedAnnotationTypes("xxx.MyAnnotation ")
    @SupportedSourceVersion(SourceVersion.RELEASE_8)
    public class MyAnnotationProcessor extends AbstractProcessor {

    public MyAnnotationProcessor () {
    super();
    }

    @Override
    public boolean process(Set<? extends TypeElement> typeElementSet, RoundEnvironment roundEnv) {

    for (Element e : roundEnv.getRootElements()) {
    String className = e.toString();
    String message = "Annotated class - " + className;
    System.out.println(message);
    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
    }

    return false;
    }
    }

    (C) 在目录中创建 javax.annotation.processing.Processor 文件 - src/main/resources/META-INF/services内容如下-

    xxx.MyAnnotationProcessor

    (D) 使用构建配置更新 pom.xml -

    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
    <verbose>true</verbose>
    <fork>true</fork>
    <compilerArgument>-proc:none</compilerArgument>
    </configuration>
    </plugin>
    </plugins>
    </build>

    (E) 使用 mvn clean install 编译并安装此项目。

  2. 创建另一个 Maven 项目 - Annotation_User - 该项目将使用上述项目中定义的注解。在此项目中创建 2 个源文件并使用此注释进行注释

    (A) AnnotationUser1 -

    package xxx.consumer;

    import xxx.MyAnnotation;

    @MyAnnotation
    public class AnnotationUser1 {

    private String message;

    public AnnotationUser1(String message) {
    this.message = message;
    }

    public String getMessage() {
    return message;
    }

    public void setMessage(String message) {
    this.message = message;
    }

    }

    (B) AnnotationUser2 -

    package xxx.consumer;

    import xxx.MyAnnotation;

    @MyAnnotation
    public class AnnotationUser2 {

    private String message;

    public AnnotationUser1(String message) {
    this.message = message;
    }

    public String getMessage() {
    return message;
    }

    public void setMessage(String message) {
    this.message = message;
    }

    }

    (C) 使用Annotation项目依赖更新pom.xml -

    <dependency>
    <groupId>xxx</groupId>
    <artifactId>Annotation_Compile_Time</artifactId>
    <version>1.0</version>
    </dependency>

现在,无论何时,您将使用mvn clean compile 编译此项目,您在项目 1 中定义的注释处理器将被调用。目前,处理器只是打印使用此注释注释的类的名称。

也可以引用this详情页面。

下一步是分析源文件并计算编号。的方法。因为,它是编译时处理,所以你不能使用 Reflection API 来获取 no。的方法。一种解决方案是使用 Eclipse AST用于解析源文件并计算编号。方法,或者您可以编写自己的逻辑。

Project lombok主要是基于Compile-time注解处理。想做点有用的,不如好好研究一下Project lombok source code

关于java - 如何像FunctionalInterface一样实现注解来限制成员函数的数量、函数类型等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48570033/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com