查看: 9454|回复: 0

如何在 Java 中创建可重复的注解

[复制链接]
  • TA的每日心情
    开心
    2021-10-18 01:53
  • 签到天数: 41 天

    [LV.5]常住居民I

    发表于 2021-9-20 01:39:11 | 显示全部楼层 |阅读模式
    本帖最后由 by鬼神 于 2021-9-20 03:36 编辑

    介绍
    在 Java 8@Repeatable中引入,这是创建重复注释的推荐方法。我们仍然需要创建一个持有者注释(持有其他注释数组的注释),但我们不再需要在调用点声明持有者注释。

    本教程旨在向您展示使用@Repeatable.

    目标
    在本教程结束时,您将学到:

    • 如何创建自己的自定义注释。
    • 如何创建可重复的注释。

    必备知识
    • 基本Java
    • 反射API的基础知识。
    • 对注解的基本理解。

    所需工具
    • 至少支持 JDK 8 的 Java IDE。

    项目设置
    要按照本教程进行操作,请执行以下步骤:

    • 创建一个新的 Java 项目。
    • 创建一个包com.example。
    • 创建一个名为Entry.java. 这就是我们的main()方法存在的地方。
    • 根据com.example包,创建3个公共类:

    一。Banana
    湾 Cat
    C。Bike
    自定义注释审查
    我遇到的大多数 Java 开发人员都告诉我,他们从来不必创建自己的自定义注解,即使他们每天都使用注解(@Override)。为其他开发人员提供开箱即用的注解通常是框架的工作。

    本教程的这一部分为不熟悉语法的人提供了如何创建自定义 Annotations 的快速概述,或者为那些忘记了的人提供了复习。

    将下面的代码复制并粘贴到您的Cat.java文件中。
    [Java] 纯文本查看 复制代码
    package com.example;
    
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
    
        @Retention(RetentionPolicy.RUNTIME)
        @interface CatAttribute { //1
           String value(); //2
        }
    
        @CatAttribute("Cute") //3
        public class Cat { } //Single custom Annotation


    在上面的代码片段中,我们声明了一个空类Cat和一个名为 的注解CatAttribute。

    注释类似于接口。它们是隐式抽象的,不能被实例化。这就是为什么所选择的声明注释的语法也是关键字“ interface ”,但前缀为一个@符号以区分两者。

    我们在代码中看到的注释可能无法在编译时或运行时“存活”。它们是否在不同阶段被剥离或保留由枚举RetentionPolicy( CLASS, RUNTIME, SOURCE) 决定。

    您不需要使用 来注释您的自定义注释@RetentionPolicy;我只对这个代码片段这样做,因为稍后我们将检索main(). 如果您不使用 注释自定义 Annotation @RetentionPolicy,则您的注释将仅遵循由 指定的默认行为RetentionPolicy.CLASS。

    注意value()第 2 行的方法。方法value()比较特殊,术语略有变化。官方文档称它们为element而不是方法。如果valueAnnotation 中存在特殊元素,那么我们就不必在调用点再次指定单词“ value ”,因此我们能够在第 3 行直接传递“ Cute ” @CatAttribute。

    创建重复注释的旧方法
    为了理解如何使用@Repeatable,我们需要先看看旧的方式是如何工作的。

    将下面的代码复制并粘贴到Banana.java.

    [Java] 纯文本查看 复制代码
    package com.example;
    
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
    
        @interface Benefit { //1
           String value();
        }
    
        @Retention(RetentionPolicy.RUNTIME)
        @interface Benefits { //2
           Benefit[] value(); //3
        }
    
        @Benefits({ //4
               @Benefit("Nutritious"), //5
               @Benefit("Healthy") //6
        })
        public class Banana { } //The old way to doing repeatable annotation



    在上面的代码片段中,我们创建了两个不同的注释。该Benefit注解就是包含了这个类有趣的信息Banana,但Benefits(复数)注释包含数组持有其他Benefit注释。

    在第 4 行的调用点,代码变得有点难以阅读,因为我们必须声明持有者注释和持有者数组。能够Benefit直接应用多个注释Banana不是很好吗?

    @Repeatable 注解
    该@Repeatable注释可以让你做到这一点。设置后,我们将能够多次应用相同的 Annotation。

    在 中Bike.java,复制并粘贴以下代码:

    [Java] 纯文本查看 复制代码
     package com.example;
    
        import java.lang.annotation.Repeatable;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
    
        @Repeatable(BikeAttributes.class) //1
        @interface BikeAttribute { //2
           String value();
        }
    
        @Retention(RetentionPolicy.RUNTIME)
        @interface BikeAttributes { //3
           BikeAttribute[] value(); //4
        }
    
        @BikeAttribute("Agile") //5
        @BikeAttribute("Affordable") //6
        public class Bike { } //Repeatable annotation


    要使用@Repeatable,我们必须执行与使用持有者注解时几乎完全相同的步骤。唯一额外的步骤,我们必须做的是注释,需要重复注释与@Repeatable和传入类持有人annotation作为其价值的。您可以在第 1 行看到。

    即使只是糖语法,这里的好处是我们不再需要声明持有者注解,并且可以@BikeAttribute直接多次注解。

    运行时注解是什么样的?
    由于我们使用 注释了在前面步骤中创建的所有注释,因此我们@Retention(RetentionPolicy.RUNTIME)现在可以在运行时检索它们。在您的Entry.java班级中,复制并粘贴以下代码。

    [Java] 纯文本查看 复制代码
    package com.example;
    
        import java.lang.annotation.Annotation;
    
        public class Entry {
           public static void main(String[] args){
               Annotation[] catAnnotations = Cat.class.getAnnotations(); //1 getting cat annotations via reflection
               for (Annotation annotation : catAnnotations) {
                   System.out.println(annotation);
               }
    
               Annotation[] bananaAnnotations = Banana.class.getAnnotations(); //2 getting banana annotations via reflection
               for (Annotation annotation : bananaAnnotations){
                   System.out.println(annotation);
               }
    
               Annotation[] bikeAnnotations = Bike.class.getAnnotations(); //3 getting bike annotations via reflection
               for (Annotation annotation : bikeAnnotations){
                   System.out.println(annotation);
               }
           }
        }


    所有代码所做的就是获取在运行时为我们以前的类保留的注释并将它们打印出来。

    对于只注释一次的 Cat 类,我们得到:

    [Java] 纯文本查看 复制代码
     @com.example.CatAttribute("Cute")


    但是对于 Banana 和 Bike 类,它们都获得了持有者 Annotations,这进一步证明这@Repeatable只是糖语法。

    [Java] 纯文本查看 复制代码
        @com.example.Benefits({
        @com.example.Benefit("Nutritious"), 
        @com.example.Benefit("Healthy")
        })


    [Java] 纯文本查看 复制代码
        @com.example.BikeAttributes({
        @com.example.BikeAttribute("Agile"),
         @com.example.BikeAttribute("Affordable")
        })


    概括
    我们已经学习了如何创建可重复的注释。它的糖语法将使我们的代码更具可读性。

    该@Repeatable语法还使转换当前持有者注释变得非常容易。您所要做的就是添加@Repeatable到子 Annotation 并传入持有者 Annotation 的类对象。


    我叫by鬼神。我是一名 Java 开发人员,专门从事 Java/Spring/MySQL 堆栈的后端开发。

    我还可以使用 Angular/Typescript/JS/HTML/CSS 和带有 Kotlin 的原生 Android 在前端工作。

    我以后会分享更多专业知识和资源到中国红客联盟与你们一起探讨

    如果有其他问题可以在下方评论,我上线会一一解答
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-4-19 21:37 , Processed in 0.041654 second(s), 12 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部