Java 注解的玩儿法。

本贴最后更新于 2444 天前,其中的信息可能已经物是人非

元注解是指注解的注解,包括 @Retention @Target @Document @Inherited 四种。

呃,看了一眼源码其实 8(我截止到今天用的是 8,2018/8/1)里面还有 @Repeatable。
WX201808011513532xpng

先按顺序来分析:

1、@Retention 作用

定义注解的保留策略

  • @Retention(RetentionPolicy.SOURCE): 注解仅保存在源码阶段,编译和运行时都不会有。
/** * Annotations are to be discarded by the compiler. */ SOURCE,
  • @Retention(RetentionPolicy.CLASS): 注解会在 class 字节码中存在,运行时不可见。此策略为默认。
/** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS,
  • @Retention(RetentionPolicy.RUNTIME): 注解会在 class 字节码文件中存在,在运行时可以通过反射获取到
/** * 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. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME

2、@Target: 定义注解的作用目标

public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, // 类,接口,枚举,注解。 /** Field declaration (includes enum constants) */ FIELD, // 字段, 枚举常量。 /** Method declaration */ METHOD, // 方法 /** Formal parameter declaration */ PARAMETER, // 方法参数 /** Constructor declaration */ CONSTRUCTOR, // 构造函数 /** Local variable declaration */ LOCAL_VARIABLE, // 局部变量 /** Annotation type declaration */ ANNOTATION_TYPE, // 注解 /** Package declaration */ PACKAGE, // 包 /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, // 新特性,表示这个 Annotation 可以用在 Type 的声明式前 /** * Use of a type * * @since 1.8 */ TYPE_USE // 新特性,表示当前Annotation 可以用在所有使用 Type 的地方(如:泛型,类型转换等)。 }

3、@Documented

表示可以出现在 javadoc 中,

4、@Inherited

该注解表示子类可以集成加载父类上的注解。但要注意:

1.注解定义在类上面,子类是可以继承该注解的。 2.注解定义在方法上面,子类也可以继承该注解,但是如果子类复写了父类中定义了注解的方法,那么子类将无法继承该方法的注解,也就是说,子类在复写父类中被@Inherited标注的方法时,会将该方法上面的注解覆盖掉 3.Interface的实现类(implements实现)无法继承接口中所定义的被@Inherited标注的注解

@Inherited 的总结来自:
CShawnX:Java 和 Android 中的注解

5、@Repeatable 可以重复注解

在之前,相同的注解在同一个位置只能使用一次, java8 引入了重复注解机制。可以让一个注解在一个位置引用多次。例如:

@interface Persons { Person[] value(); } @Repeatable(Persons.class) @interface Person{ String role default""; } @Person(role="artist") @Person(role="coder") @Person(role="PM") public class SuperMan{ }

表示这个 SuperMan 可以是三种角色,artist,coder,PM。

上面代码中,用 @Repeatable 注解了注解 Person,而其括号内的 Persons.class 表示为一个注解容器。
按照规定,它里面必须要有一个 value 的属性,属性类型是一个被 @Repeatable 注解过的注解数组,注意它是数组。

注解怎么玩儿?

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

注解有许多用处,主要如下:

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html 文档或者做其它相应处理。
  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

玩儿法一

java 预置了一些注解,可以通过这些注解,对代码进行描述。达到某种目的。
@Deprecated、@Override、@SuppressWarnings、@SafeVarargs、@FunctionalInterface

玩儿法二

那就是自己定义一些注解了。
通过反射,获得相关的注解,并未目标增加一系列附加的处理操作。因为正像官方描述:注解对于代码的运行效果没有直接影响。但是我们可以为其增强啊。
getAnnotation()或者 getAnnotations()可以获得目标的注解对象或者所有注解的数组。再根据这些注解对象以及其成员属性。
可以据此为其编写外部能力。

应用场景

日志、测试类、Ioc、功能增强等。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 168 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3196 引用 • 8215 回帖 • 2 关注
  • 反射
    20 引用 • 29 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • JFLB0907

    都是大神😂

  • wenandlu

    以前玩过,根据实体类注解,生成列表的 excel 导出文件,还是比较实用的,也不会破坏代码结构,所以提醒一下,有个 RUNTIME 注解很重要,我曾在这里耗费过半天时间,就是没有加入 RUNTIME 注解,导致获取不到注解