首页 注解细节原理
文章
取消

注解细节原理

注解

使用方式,声明注解以及元注解。

元注解

JAVA定义注解的元注解有四个(Target, Retention,Document,Inherited)

@Target(ElementType)

注解可以应用的地方

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
public enum ElementType {
   /**标明该注解可以用于类、接口(包括注解类型)或enum声明*/
   TYPE,
 
   /** 标明该注解可以用于字段(域)声明,包括enum实例 */
   FIELD,
 
   /** 标明该注解可以用于方法声明 */
   METHOD,
 
   /** 标明该注解可以用于参数声明 */
   PARAMETER,
 
   /** 标明注解可以用于构造函数声明 */
   CONSTRUCTOR,
 
   /** 标明注解可以用于局部变量声明 */
   LOCAL_VARIABLE,
 
   /** 标明注解可以用于注解声明(应用于另一个注解上)*/
   ANNOTATION_TYPE,
 
   /** 标明注解可以用于包声明 */
   PACKAGE,
 
   /**
    * 标明注解可以用于类型参数声明(1.8新加入)
    * @since 1.8
    */
   TYPE_PARAMETER,
 
   /**
    * 类型使用声明(1.8新加入)
    * @since 1.8
    */
   TYPE_USE

@Retention(RetentionPolicy)

源码级别(source),类文件级别(class)或者运行时级别(runtime)

使用方式在注解上标明。@Retention(RetentionPolicy.RUNTIME)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public enum RetentionPolicy {
    /**
     * 注解只会保留在源码层,编译期被丢弃
     */
    SOURCE,

    /**
     * 注解保留至class字节码层,运行期被VM丢弃
     */
    CLASS,

    /**
     * 注解将会保留至运行期
     */
    RUNTIME
}

@Inherited

是否可以被子类继承, 就是在子类找一个注解找不到的时候会不会到父类里面去找这个注解信息

@Document

注解定义支持的数据类型

注解支持的数据类型有如下:

  • java原生的8种基本类型(byte, char, short, int , long , float, double, boolean)
  • String
  • Class
  • enum
  • annotation
  • 以上的数组类型

也就是说定义一个注解的时候, 注解的参数类型不可以是我们的包装类型,必须是以上的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Gauge{
  
  String name() default "";
  
  Class<?> testCase() default Void.class;
  
  Reference reference() default @Reference(next=true);
  
  long[] value; 
  
}

注解不支持继承

extends关键字不能用来使用在@interface,但是在编译后,自定义注解会自动继承Annotation接口,可以在注解编译后对其进行反编译确认。

注解中不允许有不确定元素

在注解中所有的元素要么有确定的默认值, 要么在声明使用的时候必须有指定的值,不允许有null值的存在。

注解与反射

由于注解在编译后自动继承Annotation接口。也就是说所有的注解都继承了Annotation接口, 同时为了方便运行时准确获取注解的信息, java在java.lang.reflact包中新增了AnnotationElement,主要用于表示VM中所有使用了注解的元素,可以利用反射技术获取注解的信息。

JDK8增强注解

@Repeatable

在没有这个注解前,同一个元素中不允许使用同一个注解多次

jdk8前

1
2
3
4
5
6
7
8
9
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FilterPath {
   String [] value();
}

@FilterPath({"/update","/add"})
class a{}

jdk8后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.lang.annotation.*;/**
* Created by zejian on 2017/5/20.
*/
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(FilterPaths.class)
public @interface FilterPath {
   String  value();
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface FilterPaths {
   FilterPath[] value();
}
@FilterPath("/web/update")
@FilterPath("/web/add")
@FilterPath("/web/delete")

参考

https://blog.csdn.net/lixiaoxiong55/article/details/81435829

本文由作者按照 CC BY 4.0 进行授权

Elasticsearch(2)

计算及运行基本原理