目录
java注解
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
java注解可以理解为一个标签,起到一个解释说明作用。
比如现实生活中给冰箱贴标签,给手机贴标签,给电脑贴标签,可以再细分下去,给安卓手机贴标签,给苹果手机贴标签等等,想怎么贴怎么贴,当然了再java世界肯定不能乱贴了。
知道了注解是什么之后,我们在看下注解的一些概念
元注解
什么东西是元注解呢?
元注解其实就是注解的注解,可以理解为给标签再贴标签,他是应用到注解上面的,是一种基本的注解。
为什么有元注解呢?
大家可以思考一个问题,我们现在有了一个标签(就是我们的注解),然后有一个装满了苹果的盒子(可以理解为类和方法等),那我们这个标签要怎么贴呢,是贴在盒子上,还是苹果上呢,如果这个苹果有毒,那我们是不是应该贴一个有毒的标签上去,那我们是吃的时候贴呢,还是不吃的时候贴呢(可以理解为运行时还是编译时),那么这个时候元注解就闪亮登场了,他其实就是为了解决上面的这些问题,他就是给我们的标签做一个解释说明的作用。
元注解有五个,分别是@Retention、@Documented、@Target、@Inherited、@Repeatable
@Retention
Retention的中文意思表示保留维持,当@Retention应用到一个注解上时,说明的是这个注解的保留时间。
它的取值如下:
-
RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
-
RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
-
RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
我们可以理解为这个元注解相当于给我们的标签贴上了一个时间标志,标志着这个标签的存活时间
@Documented
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。
@Target
Target 是目标的意思,@Target 指定了注解运用的地方。
-
ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
-
ElementType.CONSTRUCTOR 可以给构造方法进行注解
-
ElementType.FIELD 可以给属性进行注解
-
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
-
ElementType.METHOD 可以给方法进行注解
-
ElementType.PACKAGE 可以给一个包进行注解
-
ElementType.PARAMETER 可以给一个方法内的参数进行注解
-
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited
Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。
@Repeatable
Repeatable 是重复的意思,他标识的注解是可以重复贴在一个目标上的,比如给苹果贴上标签,红的绿的等
一般我们需要一个容器注解
这个注解用来装填我们需要被重复使用的注解
@interface Persons { Person[] value(); } @Repeatable(Persons.class) @interface Person{ String role() default ""; } @Person(role="artist") @Person(role="coder") @Person(role="PM") public class SuperMan{ }
注意上面的代码,@Repeatable 注解了 Person。而 @Repeatable 后面括号中的类相当于一个容器注解。
什么是容器注解呢?就是用来存放其它注解的地方。它本身也是一个注解。
我们再看看代码中的相关容器注解。
@interface Persons { Person[] value(); }
按照规定,它里面必须要有一个 value 的属性,属性类型是一个被 @Repeatable 注解过的注解数组,注意它是数组。
如果不好理解的话,可以这样理解。Persons 是一张总的标签,上面贴满了 Person 这种同类型但内容不一样的标签。把 Persons 给一个 SuperMan 贴上,相当于同时给他贴了程序员、产品经理、画家的标签。
注解的属性
注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
String name();
需要注意的是,在注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。
注解中可以用默认值用default表示
String name() default "" ;
加了默认值后使用注解时可以不填属性值,如果不加的话就需要填写属性值
如果只有一个属性值切名字是value时,可以直接忽略掉属性的名字
例如 @check("name")等价于@check(value="")
如果没有属性值时可以直接使用注解@check
注解的提取
通过反射提取,而且注解的target必须设置为运行时,才能提取。