目录

  • 使用 @Repeatable
  • 使用反射获取注解
  • 约束

@RepeatableJDK1.8 增加的元注解,用于声明当前注解是可重复的。如果有没有声明 @Repeatable,在同一个地方使用相同的注解将编译报错。

代码实践一下

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {String value();
}

在类上多次使用 @Value 注解,会报错,代码无法编译。

// 此处会报编译错误
@Value(value = "B")
@Value(value = "C")
public class AnnotationClass {}

使用 @Repeatable

1、在 @Value 注解上添加 @Repeatable 元注解,@Repeatable 里面的的值是 @Value 的集合注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Values.class)
public @interface Value {String value();
}

2、Values 注解,value 方法的返回值为 @Value 数组

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Values {Value[] value();
}

经过改造之后,AnnotationClass 的编译错误消失了。

// 不再报错了
@Value(value = "B")
@Value(value = "C")
public class AnnotationClass {}

使用反射获取注解

@Value(value = "B")
@Value(value = "C")
public class AnnotationClass {public static void main(String[] args) throws Exception {System.out.println(AnnotationClass.class.getAnnotation(Value.class));Annotation[] annotations = AnnotationClass.class.getAnnotations();System.out.println(annotations.length);System.out.println(Arrays.toString(annotations));}}

输出结果如下,可以看到,虽然在代码上看,我们使用了两个 @Value 注解,但是直接获取 @Value 注解却没有获取到,而获取全部注解长度也只有 1,这个注解就是 @Values 注解。从结果可以反推出,当使用多个注解时,JDK 会在编译期转换为 @Repeatable 中声明的集合注解。

null
1
[@Values(value=[@Value(value=B), @Value(value=C)])]

约束

  • @Target 范围,单个注解范围必须大于等于集合注解。

@Value 范围比 @Values 大,正常编译

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Values.class)
public @interface Value {String value();
}@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Values {Value[] value();
}

@Value 范围比 @Values 小,编译报错

// Target of container annotation 'Values' is not a subset of target of this annotation
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Values.class)
public @interface Value {String value();
}@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Values {Value[] value();
}
  • @Retention 范围,单个注解范围必须小于等于集合注解

SOURCE(源码) < CLASS (字节码) < RUNTIME(运行)

@Value 范围比 @Values 大,编译报错

// Container annotation 'Values' has shorter retention ('CLASS') than the contained annotation
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Values.class)
public @interface Value {String value();
}@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface Values {Value[] value();
}

JAVA注解 | 可重复元注解@Repeatable相关推荐

  1. java元注解_Java的元注解

    注解是一系列元数据,它利用元数据来解释.说明程序代码(即被注解的对象).注解的作用包括: 1.提供信息给编译器,编译器可以利用注解来探测错误和警告信息. 2.软件工具可以利用注解信息来生成代码.HTM ...

  2. 「SpringBoot 相关注解」@Retention 元注解

    @Retention 介绍 Retention.java 类位于 JDK 的 rt.jar 内,属于一个 JDK 注解 它是用来修饰注解的,是注解的注解,称之为元注解 @Documented @Ret ...

  3. 注解(7)_元注解_元注解的概念_@Retention_@Target_@Documented_@Inherited

    元注解的概念 元注解是用于修饰其他注解的注解. (1)元注解本身也是注解. (2)元注解是用来修饰别的注解的. JDK5.0提供了四种元注解: @Retention @Target @Document ...

  4. 深入理解java注解,java的4个元注解,注解三要素——定义、使用及读取执行,深入了解注解的底层本质,通过反射自动、动态获取注解所有属性以及属性值

    1. 注解的定义 注解也是一种引用类型,编译后会生成 .class 字节码文件,作用就是为程序进行标识,不同注解能实现不同功能. 2. 注解的使用 3. 注解的读取执行 3.1 得不到注解信息,得到的 ...

  5. java 元注解 @Repeatable

    目录 一 笔记 二 自定义注解容器Persons 三 自定义的注解AnnotationTest08_Person ,即可重复使用的注解 四 通过反射机制获取重复注解的信息 一 笔记 元注解 @Repe ...

  6. c JAVA 注解,Java元注解作用及使用

    元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解.Java 5 定义了 4 个注解,分别是 @Documented.@Target.@Retention 和 @Inherited.Ja ...

  7. Java元注解作用及使用

    元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解.Java 5 定义了 4 个注解,分别是 @Documented.@Target.@Retention 和 @Inherited.Ja ...

  8. java path 注解_Java内置系统注解和元注解

    第一节:注解(Annotation)的作用 Annotation(注解)是JDK5.0及以后版本引入的.它的作用是修饰程序元素.什么是程序元素呢?例如:包.类.构造方法.方法.成员变量等. 注解,就是 ...

  9. 【Java 注解】自定义注解 ( 元注解 )

    文章目录 一.元注解 二.常用的元注解类型 三.@Target 元注解 四.@Retention 元注解 五.@Documented 元注解 六.@Documented 元注解 一.元注解 元注解 是 ...

最新文章

  1. dispatcherservlet发送2次请求_Spring源码分析(三):MVC请求分发器DispatcherServlet设计实现...
  2. 在线答题系统开发经验mysql,php
  3. python怎么读取txt文件内容然后保存到excel-Python实现读取txt文件并转换为excel的方法示例...
  4. :before 和 :after
  5. 老黄历接口(免注册)
  6. android sdio 时钟 ios-clock,iOS 炫酷时钟
  7. 多线程 调用 axis 报错_java笔记录(三、多线程)
  8. 算法偏见是什么_算法可能会使任何人(包括您)有偏见
  9. linux每日命令(1):gzip命令
  10. Visual Studio的语法着色终于调得赏心悦目
  11. el table 固定表头和首行_vue表格实现固定表头首列
  12. Vue -- 如何在 span 标签上实现一个点击事件
  13. Why not inherit from ListT?
  14. CEBX格式的文档如何转换为PDF格式文档、DOCX文档?
  15. java收费站开发流程,TLQ安装说明
  16. RTF(rich textformat)富文本格式
  17. Cron每年1月5号 4月5号 7月5号 10月5号 00:00:00执行任务
  18. 金融计量模型(十):协整和误差修正模型
  19. linux日常常用命令介绍——实用、简单明了不啰嗦
  20. linux搭建虚拟化平台报告,Centos部署KVM虚拟化平台(可跟做)

热门文章

  1. LS1046A 网卡顺序调整,失败的情况解决
  2. 基于神经网络的手写汉字提取与书写评分模型研究
  3. SAP FI 会计凭证
  4. 绝影疯狂的程序员经典语录(完结)
  5. Jmeter设置CSV Data Set Config,未读取文件中参数的原因
  6. World Wind Java开发之六——解析shape文件
  7. html字数检测,检测已经输入字数.html
  8. zookeeper镜像删除报错:Error response from daemon:xxxxx…
  9. 大端和小端传输字节序
  10. JavaFX制作水墨大写意画板程序