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

举报
韩曙亮 发表于 2022/01/10 23:43:00 2022/01/10
【摘要】 文章目录 一、元注解二、常用的元注解类型三、@Target 元注解四、@Retention 元注解五、@Documented 元注解六、@Documented 元注解 一、元...





一、元注解



元注解 是 描述 注解注解 ;


以 Override 注解为例 , 分析下该注解的 元注解 含义 :

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

  
 
  • 1
  • 2
  • 3
  • 4

@Target 注解用于说明该注解作用位置 , ElementType.METHOD 表示该注解用于标注 方法 ; 注解的作用位置 : 包 , 类 , 成员变量 , 方法 , 方法参数 , 局部变量 , 6 6 6 个作用位置 ;

@Retention 注解用于说明该注解需要保留到什么阶段 , RetentionPolicy.SOURCE 表示保留到源码中 , SOURCE 阶段 ( 源代码阶段 ) ; Java 代码的三个阶段分别是 : 源代码阶段 , 类对象阶段 , 运行时阶段 ;

元注解的个数是有限的 , JDK 已经定义好 ;





二、常用的元注解类型



@Target : 描述 注解 的作用位置 , 包 , 类 , 成员变量 , 方法 , 方法参数 , 局部变量 , 6 6 6 个作用位置 ;

@Retention : 描述 注解 被保留的阶段 , 源代码阶段 , 类对象阶段 , 运行时阶段 ;

@Documented : 描述 注解 是否需要被抽取到文档中 , 在使用 javadoc 命令生成文档时 , 该 注解 是否生成到文档中 ;

@Inherited : 描述 注解 是否被子类继承 , 如果添加了该注解 , 则子类会自动继承父类的注解 ;





三、@Target 元注解



查看 Target 注解的源码 , 该注解只有 1 1 1 个注解属性 , 且属性值是 value , 因此在给 注解属性 赋值时 , 可以省略 注解属性名称 ;

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

value 注解属性 的类型是 ElementType[] 数组类型 , 代表 注解 作用的位置 ; 可以设置的位置参考 ElementType 枚举类 ;

  • ElementType.TYPE : 注解作用于类上 ;
  • ElementType.FIELD: 注解作用于字段上 ;
  • ElementType.METHOD : 注解作用于方法上 ;
public enum ElementType {
    /** 类 , 接口 (包括注解类型) , 枚举类型 声明 */
    TYPE,

    /** 字段 (包括枚举常量) */
    FIELD,

    /** 方法声明 */
    METHOD,

    /** 普通参数声明 */
    PARAMETER,

    /** 构造函数声明 */
    CONSTRUCTOR,

    /** 局部变量声明 */
    LOCAL_VARIABLE,

    /** 注解类型声明 */
    ANNOTATION_TYPE,

    /** 包声明 */
    PACKAGE,

    /**
     * 类型参数声明
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 使用一个类型
     *
     * @since 1.8
     */
    TYPE_USE
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

@Target 使用示例 : 使用 @Target(ElementType.TYPE) 设置注解作用位置必须是 类 / 接口 / 枚举 , 将 @Annotation 标注在其它位置会报错 ;

@Target(ElementType.TYPE)
public @interface Annotation {
}

  
 
  • 1
  • 2
  • 3

作用域构造函数上 , 报如下错误 ;

在这里插入图片描述

@Target(ElementType.TYPE) 元注解修饰的 Annotation 注解 , 只能在 类 上进行标注 ;

@Annotation(
        stringValue = "tom",
        enumValue = Number.ONE,
        annotationValue = @Annotation2,
        stringArrayValue = {"tom", "jerry"})
public class Student {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Target 注解中 , ElementType[] value() 注解属性的类型是数组类型 , 说明可以设置多个 注解 标注 位置 ;

如 : 使用如下

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})

  
 
  • 1

元注解修饰 Annotation 注解 , 则可以同时在 类 , 字段 和 方法上使用该 Annotation 注解 ;





四、@Retention 元注解



@Retention 注解用于说明该注解需要保留到什么阶段 ;

Java 代码的三个阶段分别是 : 源代码阶段 , 类对象阶段 , 运行时阶段 ;

查看 Retention 源码 ,

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Retention 注解的 注解属性 RetentionPolicy value() , 其类型是 RetentionPolicy 枚举类型 , 三个枚举值 , 分别对应 Java 代码三大阶段 源代码阶段 , 类对象阶段 , 运行时阶段 ;

public enum RetentionPolicy {
    /** 
     * 源代码阶段
     * 编译器丢弃该注解.
     */
    SOURCE,

    /** 
     * 类对象阶段
     * 注解会被保存到字节码文件中, 不会被 JVM 读取到.
     */
    CLASS,

    /** 
     * 运行时阶段
     * 注解会被保存到字节码文件中, 并会被 JVM 读取到.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

一般情况下 , 开发则自定义注解 , 都是在运行时进行一些代码分析 , 设置 RetentionPolicy.RUNTIME 注解属性 ;

@Retention(RetentionPolicy.RUNTIME)

  
 
  • 1




五、@Documented 元注解



如果添加了该注解 , 表示当前注解会被抽取到 Java API 文档中 ;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

使用 javadoc Student.java 命令 , 生成 Java 文档 ; 如果使用 @Documented 注解修饰 Annotation 注解 , 则导出的文档如下 , 在类和方法的上面会显示相应注解 ;

在这里插入图片描述

如果不使用 @Documented 注解 , 则生成的文档中没有 Annotation 注解 ;





六、@Documented 元注解



@Inherited : 描述 注解 是否被子类继承 , 如果添加了该注解 , 则子类会自动继承父类的注解 ;

使用 @Inherited 元注解 标注 Annotation 注解 ;

使用 Annotation 注解 标注父类 Person ;

子类 Student 继承 Person 类 , 子类中不添加注解 , 那么父类 Person 中的注解自动添加给子类 Student ;

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/116927902

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。