Java的注解

时间:2021-6-7 作者:qvyue

1. 定义

java注解是JDK1.5引进的一种技术,注解本身是一种元数据,元数据就是描述数据的数据,它对程序本身没有任何的影响。配合反射可以在运行时处理注解,配合apt tool可以在编译使处理注解,apt tool在JDK1.6已经被整合到javac中。

2. 作用

注解对程序的起到标识和传值的作用,对本身的程序运用并没有影响。可以配合反射(运行时的注解)和自定义注解处理器(编译时的注解)处理注解。java本身也内置一些注解,比如@Override表示重写父类的方法,@Deprecated表示改方法或属性已经过时。

3. 入门

3.1 定义

在Java中通过@interface来表示这是一个注解:

public @interface AnnotationTest {
}

3.2 元注解

仅仅像上面定义一个注解是没用的,还需要有元注解的修饰,所谓的元注解,就是注解的注解。java的元注解包括:@Retention、@Target、@Documented、@Inherited、@Repeatable。

@Retention 保留的意思,即注解的生命周期保留到什么时候,它有三个保留阶段,范围逐渐增大

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
  /**
   * Returns the retention policy.
   * @return the retention policy
   */
  RetentionPolicy value();
}
类型 范围
RetentionPolicy.RUNTIME 注解可以保留在运行时、编译、源码期间,可以通过反射、注解处理器获得
RetentionPolicy.CLASS 注解可以保留在编译阶段,但在虚拟机运行阶段时会被丢弃,可以通过注解处理器获得
RetentionPolicy.SOURCE 注解只保留在源码阶段,在编译器编译时就会被丢弃。
@Retention(RetentionPolicy.RUNTIME)  // 运行、编译、源码阶段
@Retention(RetentionPolicy.CLASS)  // 编译阶段
@Retention(RetentionPolicy.SOURCE) // 源码阶段
public @interface AnnotationTest {
}

@Target 翻译是目标的意思,表示注解能标识于什么类型中

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
  /**
   * Returns an array of the kinds of elements an annotation type
   * can be applied to.
   * @return an array of the kinds of elements an annotation type
   * can be applied to
   */
  ElementType[] value();
}
类型 范围
ElementType.TYPE 注解目标在类,接口(包括注解接口)、枚举类
ElementType.FIELD 注解目标在属性变量(包括枚举)
ElementType.METHOD 注解目标在方法
ElementType.PARAMETER 注解目标在方法的形式参数
ElementType.CONSTRUCTOR 注解目标在构造方法
ElementType.LOCAL_VARIABLE 注解目标在局部变量声明。
ElementType.ANNOTATION_TYPE 注解目标在注解类中
ElementType.PACKAGE 注解目标在包中
ElementType.TYPE_PARAMETER 1.8后才支持,泛型类型
ElementType.TYPE_USE 1.8后才支持,除了PACKAGE外的所有类型。
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.METHOD})
public @interface AnnotationTest {
}

@Documented将注解的元素包含在javadoc中

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

@Inherited有该元注解修饰的注解,注解标识的父类,子类同样有该注解

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
@Inherited()
public @interface AnnotationTest {
}

@AnnotationTest
public abstract class A {
}

public class B extends A {
}

这里的子类B,由于AnnotationTest注解被@Inherited修饰有继承关系,所以B也继承了AnnotationTest注解。

@Repeatable是JDK1.8才加入的一个元注解,这个的作用就是允许同一个注解在一个类型上标注多次。

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Filters.class)
public @interface Filter {
  String value();
}

@Retention(RetentionPolicy.RUNTIME)
@interface Filters {
  Filter[] value();
}

3.3 属性

注解只能起到标识的作用,如果想要传递参数,可以通过给注解设置属性来传递参数。
注解的属性设置跟类的属性设置不一样,但跟类的方法设置相似。

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface AnnotationTest {
  int age();

  String name();
}

注解的属性的赋值,通过名字来设置:

@AnnotationTest(age = 12, name = "zhangsan")
public abstract class A {
}

也可以给注解的属性设置默认值,那赋值时可以不用写:

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface AnnotationTest {
  int age() default 20;

  String name();
}

@AnnotationTest(name = "zhangsan")
public abstract class A {
}

如果你的属性只有一个,而且属性的名字是value,那么在赋值时可以不写名字:

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface AnnotationTest {
  int value();
}

@AnnotationTest(23)
public abstract class A {
}
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。